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:
parent
3fcf8b6f4b
commit
dbc603b7d7
@ -1455,13 +1455,16 @@ void CBattleInterface::bSpellf()
|
||||
|
||||
CCS->curh->changeGraphic(0,0);
|
||||
|
||||
const CGHeroInstance * chi = NULL;
|
||||
if(attackingHeroInstance->tempOwner == curInt->playerID)
|
||||
chi = attackingHeroInstance;
|
||||
else
|
||||
chi = defendingHeroInstance;
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), chi, curInt);
|
||||
GH.pushInt(spellWindow);
|
||||
if ( myTurn && curInt->cb->battleCanCastSpell())
|
||||
{
|
||||
const CGHeroInstance * chi = NULL;
|
||||
if(attackingHeroInstance->tempOwner == curInt->playerID)
|
||||
chi = attackingHeroInstance;
|
||||
else
|
||||
chi = defendingHeroInstance;
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), chi, curInt);
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::bWaitf()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,47 +23,56 @@
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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 }
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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.second = creature["number"].Float();
|
||||
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,72 +3035,70 @@ 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 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
|
||||
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
|
||||
|
||||
BOOST_FOREACH(ConstTransitivePtr<CCreature> &crea, VLC->creh->creatures)
|
||||
{
|
||||
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;
|
||||
else
|
||||
factor = -3;
|
||||
|
||||
int sympathy = 0;
|
||||
|
||||
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
|
||||
totalCount = 0;
|
||||
|
||||
for (TSlots::const_iterator i = h->Slots().begin(); i != h->Slots().end(); i++)
|
||||
{
|
||||
if(vstd::contains(myKindCres,i->second->type->idNumber))
|
||||
count += i->second->count;
|
||||
totalCount += i->second->count;
|
||||
}
|
||||
|
||||
if(count*2 > totalCount)
|
||||
sympathy++;
|
||||
if(count)
|
||||
sympathy++;
|
||||
|
||||
|
||||
int charisma = factor + h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy;
|
||||
if(charisma >= character) //creatures might join...
|
||||
{
|
||||
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
|
||||
}
|
||||
if(vstd::contains(crea->upgrades, (ui32) id)) //it's our base creatures
|
||||
myKindCres.insert(crea->idNumber);
|
||||
}
|
||||
|
||||
//we are still here - creatures not joined heroes, test for fleeing
|
||||
int count = 0, //how many creatures of similar kind has hero
|
||||
totalCount = 0;
|
||||
|
||||
//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
|
||||
)
|
||||
for (TSlots::const_iterator i = h->Slots().begin(); i != h->Slots().end(); i++)
|
||||
{
|
||||
if(vstd::contains(myKindCres,i->second->type->idNumber))
|
||||
count += i->second->count;
|
||||
totalCount += i->second->count;
|
||||
}
|
||||
|
||||
int sympathy = 0; // 0 if hero have no similar creatures
|
||||
if(count)
|
||||
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;
|
||||
|
||||
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 have not joined hero, flee or fight
|
||||
|
||||
if (charisma > character)
|
||||
return -1; //flee
|
||||
else
|
||||
return -2; //fight
|
||||
|
||||
}
|
||||
|
||||
void CGCreature::fleeDecision(const CGHeroInstance *h, ui32 pursue) const
|
||||
|
@ -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
|
||||
|
@ -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); \
|
||||
|
@ -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
|
||||
|
@ -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,8 +1131,16 @@ void CGameHandler::newTurn()
|
||||
iw.text.addReplacement2(15); //%+d 15
|
||||
break;
|
||||
default:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, (newMonth ? 130 : 133));
|
||||
iw.text.addReplacement(MetaString::ARRAY_TXT, 43 + rand()%15);
|
||||
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++)
|
||||
{
|
||||
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user