1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

- reorganized hero classes

- artifact iconIndex should work
- new file with hardcoded string constants: lib/StringConstants.h

Note: some minor bugs, will fix soon:
- slow to open hero window
- hero adventure map images serialization is broken\incorrect
This commit is contained in:
Ivan Savenko 2012-12-14 15:32:53 +00:00
parent afe3f77a59
commit ffe8b99369
31 changed files with 2786 additions and 1355 deletions

View File

@ -12,6 +12,7 @@
#include "../lib/CTownHandler.h" #include "../lib/CTownHandler.h"
#include "../lib/NetPacks.h" #include "../lib/NetPacks.h"
#include "../lib/CHeroHandler.h" #include "../lib/CHeroHandler.h"
#include "../lib/StringConstants.h"
#include "CAdvmapInterface.h" #include "CAdvmapInterface.h"
#include "CAnimation.h" #include "CAnimation.h"
#include "CGameInfo.h" #include "CGameInfo.h"

View File

@ -239,7 +239,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
//loading hero animations //loading hero animations
if(hero1) // attacking hero if(hero1) // attacking hero
{ {
int type = hero1->type->heroType; int type = hero1->type->heroClass->id;
if ( type % 2 ) type--; if ( type % 2 ) type--;
if ( hero1->sex ) type++; if ( hero1->sex ) type++;
attackingHero = new CBattleHero(graphics->battleHeroes[type], false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : NULL, this); attackingHero = new CBattleHero(graphics->battleHeroes[type], false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : NULL, this);
@ -251,7 +251,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
} }
if(hero2) // defending hero if(hero2) // defending hero
{ {
int type = hero2->type->heroType; int type = hero2->type->heroClass->id;
if ( type % 2 ) type--; if ( type % 2 ) type--;
if ( hero2->sex ) type++; if ( hero2->sex ) type++;
defendingHero = new CBattleHero(graphics->battleHeroes[type ], true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : NULL, this); defendingHero = new CBattleHero(graphics->battleHeroes[type ], true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : NULL, this);
@ -1142,7 +1142,7 @@ void CBattleInterface::setBattleCursor(const int myNumber)
while (sectorCursor[(cursorIndex + i)%sectorCursor.size()] == -1) //Why hast thou forsaken me? while (sectorCursor[(cursorIndex + i)%sectorCursor.size()] == -1) //Why hast thou forsaken me?
i = i <= 0 ? 1 - i : -i; // 0, 1, -1, 2, -2, 3, -3 etc.. i = i <= 0 ? 1 - i : -i; // 0, 1, -1, 2, -2, 3, -3 etc..
int index = (cursorIndex + i)%sectorCursor.size(); //hopefully we get elements from sectorCursor int index = (cursorIndex + i)%sectorCursor.size(); //hopefully we get elements from sectorCursor
cursor->changeGraphic(1, sectorCursor[index]); cursor->changeGraphic(ECursor::COMBAT, sectorCursor[index]);
switch (index) switch (index)
{ {
case 0: case 0:
@ -1182,7 +1182,7 @@ void CBattleInterface::bOptionsf()
if(spellDestSelectMode) //we are casting a spell if(spellDestSelectMode) //we are casting a spell
return; return;
CCS->curh->changeGraphic(0,0); CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
Rect tempRect = genRect(431, 481, 160, 84); Rect tempRect = genRect(431, 481, 160, 84);
tempRect += pos.topLeft(); tempRect += pos.topLeft();
@ -1238,7 +1238,7 @@ void CBattleInterface::bFleef()
void CBattleInterface::reallyFlee() void CBattleInterface::reallyFlee()
{ {
giveCommand(BattleAction::RETREAT,0,0); giveCommand(BattleAction::RETREAT,0,0);
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
void CBattleInterface::reallySurrender() void CBattleInterface::reallySurrender()
@ -1250,7 +1250,7 @@ void CBattleInterface::reallySurrender()
else else
{ {
giveCommand(BattleAction::SURRENDER,0,0); giveCommand(BattleAction::SURRENDER,0,0);
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
} }
@ -1265,7 +1265,7 @@ void CBattleInterface::bSpellf()
if(spellDestSelectMode) //we are casting a spell if(spellDestSelectMode) //we are casting a spell
return; return;
CCS->curh->changeGraphic(0,0); CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
if(!myTurn) if(!myTurn)
return; return;
@ -1585,7 +1585,7 @@ void CBattleInterface::battleFinished(const BattleResult& br)
void CBattleInterface::displayBattleFinished() void CBattleInterface::displayBattleFinished()
{ {
CCS->curh->changeGraphic(0,0); CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19); SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
resWindow = new CBattleResultWindow(*bresult, temp_rect, this); resWindow = new CBattleResultWindow(*bresult, temp_rect, this);
@ -2076,7 +2076,7 @@ void CBattleInterface::endCastingSpell()
spellToCast = NULL; spellToCast = NULL;
sp = NULL; sp = NULL;
spellDestSelectMode = false; spellDestSelectMode = false;
CCS->curh->changeGraphic(1, 6); CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER);
if (activeStack) if (activeStack)
{ {
@ -2762,7 +2762,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
//used when hovering -> tooltip message and cursor to be set //used when hovering -> tooltip message and cursor to be set
std::string consoleMsg; std::string consoleMsg;
bool setCursor = true; //if we want to suppress setting cursor bool setCursor = true; //if we want to suppress setting cursor
int cursorType = ECursor::COMBAT, cursorFrame = ECursor::COMBAT_POINTER; //TODO: is this line used? ECursor::ECursorTypes cursorType = ECursor::COMBAT;
int cursorFrame = ECursor::COMBAT_POINTER; //TODO: is this line used?
//used when l-clicking -> action to be called upon the click //used when l-clicking -> action to be called upon the click
std::function<void()> realizeAction; std::function<void()> realizeAction;
@ -3256,7 +3257,7 @@ BattleHex CBattleInterface::fromWhichHexAttack(BattleHex myNumber)
{ {
//TODO far too much repeating code //TODO far too much repeating code
BattleHex destHex = -1; BattleHex destHex = -1;
switch(CCS->curh->number) switch(CCS->curh->frame)
{ {
case 12: //from bottom right case 12: //from bottom right
{ {

View File

@ -173,7 +173,7 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
if(myOwner->bfield[it]->hovered && myOwner->bfield[it]->strictHovered) if(myOwner->bfield[it]->hovered && myOwner->bfield[it]->strictHovered)
return; return;
} }
CCS->curh->changeGraphic(0,0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, myOwner->curInt); CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, myOwner->curInt);
GH.pushInt(spellWindow); GH.pushInt(spellWindow);

View File

@ -100,7 +100,7 @@ void CTerrainRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
if(tHovered != pom) //tile outside the map if(tHovered != pom) //tile outside the map
{ {
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
return; return;
} }
@ -116,7 +116,7 @@ void CTerrainRect::hover(bool on)
if (!on) if (!on)
{ {
adventureInt->statusbar.clear(); adventureInt->statusbar.clear();
CCS->curh->changeGraphic(0,0); CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
} }
//Hoverable::hover(on); //Hoverable::hover(on);
} }
@ -634,7 +634,7 @@ void CAdvMapInt::deactivate()
{ {
scrollingDir = 0; scrollingDir = 0;
CCS->curh->changeGraphic(0,0); CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
kingOverview.deactivate(); kingOverview.deactivate();
underground.deactivate(); underground.deactivate();
questlog.deactivate(); questlog.deactivate();
@ -1213,7 +1213,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
{ {
if(!LOCPLINT->cb->isVisible(mapPos)) if(!LOCPLINT->cb->isVisible(mapPos))
{ {
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
statusbar.clear(); statusbar.clear();
return; return;
} }
@ -1247,18 +1247,18 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
{ {
case Spells::SCUTTLE_BOAT: case Spells::SCUTTLE_BOAT:
if(objAtTile && objAtTile->ID == Obj::BOAT) if(objAtTile && objAtTile->ID == Obj::BOAT)
CCS->curh->changeGraphic(0, 42); CCS->curh->changeGraphic(ECursor::ADVENTURE, 42);
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
return; return;
case Spells::DIMENSION_DOOR: case Spells::DIMENSION_DOOR:
{ {
const TerrainTile *t = LOCPLINT->cb->getTile(mapPos, false); const TerrainTile *t = LOCPLINT->cb->getTile(mapPos, false);
int3 hpos = selection->getSightCenter(); int3 hpos = selection->getSightCenter();
if((!t || t->isClear(LOCPLINT->cb->getTile(hpos))) && isInScreenRange(hpos, mapPos)) if((!t || t->isClear(LOCPLINT->cb->getTile(hpos))) && isInScreenRange(hpos, mapPos))
CCS->curh->changeGraphic(0, 41); CCS->curh->changeGraphic(ECursor::ADVENTURE, 41);
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
return; return;
} }
} }
@ -1271,14 +1271,14 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
if(objAtTile) if(objAtTile)
{ {
if(objAtTile->ID == Obj::TOWN && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner)) if(objAtTile->ID == Obj::TOWN && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner))
CCS->curh->changeGraphic(0, 3); CCS->curh->changeGraphic(ECursor::ADVENTURE, 3);
else if(objAtTile->ID == Obj::HERO && objAtTile->tempOwner == LOCPLINT->playerID) else if(objAtTile->ID == Obj::HERO && objAtTile->tempOwner == LOCPLINT->playerID)
CCS->curh->changeGraphic(0, 2); CCS->curh->changeGraphic(ECursor::ADVENTURE, 2);
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
else if(const CGHeroInstance *h = curHero()) else if(const CGHeroInstance *h = curHero())
{ {
@ -1291,18 +1291,18 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
if(!LOCPLINT->cb->getPlayerRelations( LOCPLINT->playerID, objAtTile->tempOwner)) //enemy hero if(!LOCPLINT->cb->getPlayerRelations( LOCPLINT->playerID, objAtTile->tempOwner)) //enemy hero
{ {
if(accessible) if(accessible)
CCS->curh->changeGraphic(0, 5 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
else //our or ally hero else //our or ally hero
{ {
if(selection == objAtTile) if(selection == objAtTile)
CCS->curh->changeGraphic(0, 2); CCS->curh->changeGraphic(ECursor::ADVENTURE, 2);
else if(accessible) else if(accessible)
CCS->curh->changeGraphic(0, 8 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 8 + turns*6);
else else
CCS->curh->changeGraphic(0, 2); CCS->curh->changeGraphic(ECursor::ADVENTURE, 2);
} }
} }
else if(objAtTile->ID == Obj::TOWN) else if(objAtTile->ID == Obj::TOWN)
@ -1315,30 +1315,30 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
// Show movement cursor for unguarded enemy towns, otherwise attack cursor. // Show movement cursor for unguarded enemy towns, otherwise attack cursor.
if (townObj && !townObj->armedGarrison()) if (townObj && !townObj->armedGarrison())
CCS->curh->changeGraphic(0, 9 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 9 + turns*6);
else else
CCS->curh->changeGraphic(0, 5 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
} }
else else
{ {
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
} }
else //our or ally town else //our or ally town
{ {
if(accessible) if(accessible)
CCS->curh->changeGraphic(0, 9 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 9 + turns*6);
else else
CCS->curh->changeGraphic(0, 3); CCS->curh->changeGraphic(ECursor::ADVENTURE, 3);
} }
} }
else if(objAtTile->ID == Obj::BOAT) else if(objAtTile->ID == Obj::BOAT)
{ {
if(accessible) if(accessible)
CCS->curh->changeGraphic(0, 6 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 6 + turns*6);
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
else if (objAtTile->ID == Obj::GARRISON || objAtTile->ID == Obj::GARRISON2) else if (objAtTile->ID == Obj::GARRISON || objAtTile->ID == Obj::GARRISON2)
{ {
@ -1349,28 +1349,28 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
// Show battle cursor for guarded enemy garrisons, otherwise movement cursor. // Show battle cursor for guarded enemy garrisons, otherwise movement cursor.
if (garrObj && garrObj->stacksCount() if (garrObj && garrObj->stacksCount()
&& !LOCPLINT->cb->getPlayerRelations( LOCPLINT->playerID, garrObj->tempOwner) ) && !LOCPLINT->cb->getPlayerRelations( LOCPLINT->playerID, garrObj->tempOwner) )
CCS->curh->changeGraphic(0, 5 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
else else
CCS->curh->changeGraphic(0, 9 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 9 + turns*6);
} }
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
else if (guardingCreature && accessible) //(objAtTile->ID == 54) //monster else if (guardingCreature && accessible) //(objAtTile->ID == 54) //monster
{ {
CCS->curh->changeGraphic(0, 5 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
} }
else else
{ {
if(accessible) if(accessible)
{ {
if(pnode->land) if(pnode->land)
CCS->curh->changeGraphic(0, 9 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 9 + turns*6);
else else
CCS->curh->changeGraphic(0, 28 + turns); CCS->curh->changeGraphic(ECursor::ADVENTURE, 28 + turns);
} }
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
} }
else //no objs else //no objs
@ -1379,29 +1379,29 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
{ {
if (guardingCreature) if (guardingCreature)
{ {
CCS->curh->changeGraphic(0, 5 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
} }
else else
{ {
if(pnode->land) if(pnode->land)
{ {
if(LOCPLINT->cb->getTile(h->getPosition(false))->terType != ETerrainType::WATER) if(LOCPLINT->cb->getTile(h->getPosition(false))->terType != ETerrainType::WATER)
CCS->curh->changeGraphic(0, 4 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 4 + turns*6);
else else
CCS->curh->changeGraphic(0, 7 + turns*6); //anchor CCS->curh->changeGraphic(ECursor::ADVENTURE, 7 + turns*6); //anchor
} }
else else
CCS->curh->changeGraphic(0, 6 + turns*6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 6 + turns*6);
} }
} }
else else
CCS->curh->changeGraphic(0, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
} }
} }
if(ourInaccessibleShipyard(objAtTile)) if(ourInaccessibleShipyard(objAtTile))
{ {
CCS->curh->changeGraphic(0, 6); CCS->curh->changeGraphic(ECursor::ADVENTURE, 6);
} }
} }
@ -1480,7 +1480,7 @@ const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *ob
{ {
const IShipyard *ret = IShipyard::castFrom(obj); const IShipyard *ret = IShipyard::castFrom(obj);
if(!ret || obj->tempOwner != player || CCS->curh->mode || (CCS->curh->number != 6 && CCS->curh->number != 0)) if(!ret || obj->tempOwner != player || CCS->curh->type || (CCS->curh->frame != 6 && CCS->curh->frame != 0))
return NULL; return NULL;
return ret; return ret;

View File

@ -624,9 +624,9 @@ void CCreatureWindow::setArt(const CArtifactInstance *art)
if (creatureArtifact) if (creatureArtifact)
{ {
if (artifactImage == NULL) if (artifactImage == NULL)
artifactImage = new CAnimImage("ARTIFACT", creatureArtifact->artType->id, 0, 466, 100); artifactImage = new CAnimImage("ARTIFACT", creatureArtifact->artType->iconIndex, 0, 466, 100);
else else
artifactImage->setFrame(creatureArtifact->artType->id); artifactImage->setFrame(creatureArtifact->artType->iconIndex);
} }
else else
artifactImage = NULL; artifactImage = NULL;

View File

@ -1569,9 +1569,9 @@ void CPlayerInterface::update()
GH.drawFPSCounter(); GH.drawFPSCounter();
// draw the mouse cursor and update the screen // draw the mouse cursor and update the screen
CCS->curh->draw1(); CCS->curh->drawWithScreenRestore();
CSDL_Ext::update(screen); CSDL_Ext::update(screen);
CCS->curh->draw2(); CCS->curh->drawRestored();
} }
int CPlayerInterface::getLastIndex( std::string namePrefix) int CPlayerInterface::getLastIndex( std::string namePrefix)

View File

@ -511,9 +511,9 @@ void CGPreGame::update()
GH.drawFPSCounter(); GH.drawFPSCounter();
// draw the mouse cursor and update the screen // draw the mouse cursor and update the screen
CCS->curh->draw1(); CCS->curh->drawWithScreenRestore();
CSDL_Ext::update(screen); CSDL_Ext::update(screen);
CCS->curh->draw2(); CCS->curh->drawRestored();
} }
void CGPreGame::openCampaignScreen(std::string name) void CGPreGame::openCampaignScreen(std::string name)
@ -808,7 +808,7 @@ void CSelectionScreen::changeSelection(const CMapInfo * to)
} }
else else
{ {
sInfo.mapGenOptions = nullptr; sInfo.mapGenOptions.reset();
} }
} }
} }
@ -2812,7 +2812,7 @@ OptionsTab::CPregameTooltipBox::CPregameTooltipBox(CPlayerSettingsHelper & helpe
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
int value; int value = PlayerSettings::NONE;
switch(CPlayerSettingsHelper::type) switch(CPlayerSettingsHelper::type)
{ {

View File

@ -203,9 +203,9 @@ CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town):
void CGarrisonSlot::setHighlight(bool on) void CGarrisonSlot::setHighlight(bool on)
{ {
if (on) if (on)
selectionImage->recActions |= UPDATE | SHOWALL; //show selectionImage->enable(); //show
else else
selectionImage->recActions &= ~(UPDATE | SHOWALL); //hide selectionImage->disable(); //hide
} }
void CGarrisonSlot::hover (bool on) void CGarrisonSlot::hover (bool on)
@ -459,16 +459,16 @@ void CGarrisonSlot::update()
if (creature) if (creature)
{ {
creatureImage->recActions |= (UPDATE | SHOWALL); creatureImage->enable();
creatureImage->setFrame(creature->iconIndex); creatureImage->setFrame(creature->iconIndex);
stackCount->recActions |= (UPDATE | SHOWALL); stackCount->enable();
stackCount->setTxt(boost::lexical_cast<std::string>(myStack->count)); stackCount->setTxt(boost::lexical_cast<std::string>(myStack->count));
} }
else else
{ {
creatureImage->recActions &= ~(UPDATE | SHOWALL); creatureImage->disable();
stackCount->recActions &= ~(UPDATE | SHOWALL); stackCount->disable();
} }
} }
@ -489,10 +489,10 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg
creatureImage = new CAnimImage(imgName, creature ? creature->iconIndex : 0); creatureImage = new CAnimImage(imgName, creature ? creature->iconIndex : 0);
if (!creature) if (!creature)
creatureImage->recActions &= ~(UPDATE | SHOWALL); creatureImage->disable();
selectionImage = new CAnimImage(imgName, 1); selectionImage = new CAnimImage(imgName, 1);
selectionImage->recActions &= ~(UPDATE | SHOWALL); //hide it selectionImage->disable();
if(Owner->smallIcons) if(Owner->smallIcons)
{ {
@ -507,7 +507,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg
stackCount = new CLabel(pos.w, pos.h, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE); stackCount = new CLabel(pos.w, pos.h, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE);
if (!creature) if (!creature)
stackCount->recActions &= ~(UPDATE | SHOWALL); stackCount->disable();
else else
stackCount->setTxt(boost::lexical_cast<std::string>(myStack->count)); stackCount->setTxt(boost::lexical_cast<std::string>(myStack->count));
} }
@ -937,7 +937,7 @@ size_t CComponent::getIndex()
case secskill: return subtype*3 + 3 + val - 1; case secskill: return subtype*3 + 3 + val - 1;
case resource: return subtype; case resource: return subtype;
case creature: return CGI->creh->creatures[subtype]->iconIndex; case creature: return CGI->creh->creatures[subtype]->iconIndex;
case artifact: return subtype; case artifact: return CGI->arth->artifacts[subtype]->iconIndex;
case experience: return 4; case experience: return 4;
case spell: return subtype; case spell: return subtype;
case morale: return val+3; case morale: return val+3;
@ -2005,7 +2005,7 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
aw->arts->markPossibleSlots(art); aw->arts->markPossibleSlots(art);
//aw->arts->commonInfo->dst.AOH = aw->arts; //aw->arts->commonInfo->dst.AOH = aw->arts;
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[art->artType->id].bitmap); CCS->curh->dragAndDropCursor(new CAnimImage("artifact", art->artType->iconIndex));
aw->arts->artifactsOnAltar.erase(art); aw->arts->artifactsOnAltar.erase(art);
id = -1; id = -1;
@ -3964,16 +3964,67 @@ void CWindowWithGarrison::updateGarrisons()
garr->recreateSlots(); garr->recreateSlots();
} }
CArtPlace::CArtPlace(const CArtifactInstance* Art)
:picked(false), marked(false), locked(false), ourArt(Art)
{
}
CArtPlace::CArtPlace(Point position, const CArtifactInstance * Art): CArtPlace::CArtPlace(Point position, const CArtifactInstance * Art):
picked(false), marked(false), locked(false), ourArt(Art) locked(false), picked(false), marked(false), ourArt(Art)
{ {
pos += position; pos += position;
pos.w = pos.h = 44; pos.w = pos.h = 44;
createImage();
}
void CArtPlace::createImage()
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
int graphic = 0;
if (ourArt)
graphic = ourArt->artType->iconIndex;
if (locked)
graphic = GameConstants::ID_LOCK;
image = new CAnimImage("artifact", graphic);
if (!ourArt)
image->disable();
selection = new CAnimImage("artifact", GameConstants::ID_SELECTION);
selection->disable();
}
void CArtPlace::lockSlot(bool on)
{
if (locked == on)
return;
locked = on;
if (on)
image->setFrame(GameConstants::ID_LOCK);
else
image->setFrame(ourArt->artType->iconIndex);
}
void CArtPlace::pickSlot(bool on)
{
if (picked == on)
return;
picked = on;
if (on)
image->disable();
else
image->enable();
}
void CArtPlace::selectSlot(bool on)
{
if (marked == on)
return;
marked = on;
if (on)
selection->enable();
else
selection->disable();
} }
void CArtPlace::clickLeft(tribool down, bool previousState) void CArtPlace::clickLeft(tribool down, bool previousState)
@ -3994,7 +4045,7 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
else else
{ {
ourOwner->unmarkSlots(false); ourOwner->unmarkSlots(false);
marked = true; selectSlot(true);
ourOwner->highlightModeCallback(this); ourOwner->highlightModeCallback(this);
} }
} }
@ -4150,19 +4201,20 @@ void CArtPlace::select ()
if (locked) if (locked)
return; return;
picked = true; selectSlot(true);
pickSlot(true);
if(ourArt->canBeDisassembled() && slotID < GameConstants::BACKPACK_START) //worn combined artifact -> locks have to disappear if(ourArt->canBeDisassembled() && slotID < GameConstants::BACKPACK_START) //worn combined artifact -> locks have to disappear
{ {
for(int i = 0; i < GameConstants::BACKPACK_START; i++) for(int i = 0; i < GameConstants::BACKPACK_START; i++)
{ {
CArtPlace *ap = ourOwner->getArtPlace(i); CArtPlace *ap = ourOwner->getArtPlace(i);
ap->picked = ourArt->isPart(ap->ourArt); ap->pickSlot(ourArt->isPart(ap->ourArt));
} }
} }
//int backpackCorrection = -(slotID - Arts::BACKPACK_START < ourOwner->backpackPos); //int backpackCorrection = -(slotID - Arts::BACKPACK_START < ourOwner->backpackPos);
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->artType->id].bitmap); CCS->curh->dragAndDropCursor(new CAnimImage("artifact", ourArt->artType->iconIndex));
ourOwner->commonInfo->src.setTo(this, false); ourOwner->commonInfo->src.setTo(this, false);
ourOwner->markPossibleSlots(ourArt); ourOwner->markPossibleSlots(ourArt);
@ -4178,11 +4230,11 @@ void CArtPlace::select ()
*/ */
void CArtPlace::deselect () void CArtPlace::deselect ()
{ {
picked = false; pickSlot(false);
if(ourArt && ourArt->canBeDisassembled()) //combined art returned to its slot -> restore locks if(ourArt && ourArt->canBeDisassembled()) //combined art returned to its slot -> restore locks
{ {
for(int i = 0; i < GameConstants::BACKPACK_START; i++) for(int i = 0; i < GameConstants::BACKPACK_START; i++)
ourOwner->getArtPlace(i)->picked = false; ourOwner->getArtPlace(i)->pickSlot(false);
} }
CCS->curh->dragAndDropCursor(NULL); CCS->curh->dragAndDropCursor(NULL);
@ -4200,8 +4252,7 @@ void CArtPlace::showAll(SDL_Surface * to)
{ {
if (ourArt && !picked && ourArt == ourOwner->curHero->getArt(slotID, false)) //last condition is needed for disassembling -> artifact may be gone, but we don't know yet TODO: real, nice solution if (ourArt && !picked && ourArt == ourOwner->curHero->getArt(slotID, false)) //last condition is needed for disassembling -> artifact may be gone, but we don't know yet TODO: real, nice solution
{ {
int graphic = locked ? GameConstants::ID_LOCK : ourArt->artType->id; CIntObject::showAll(to);
blitAt(graphics->artDefs->ourImages[graphic].bitmap, pos.x, pos.y, to);
} }
if(marked && active) if(marked && active)
@ -4246,11 +4297,14 @@ void CArtPlace::setArtifact(const CArtifactInstance *art)
ourArt = art; ourArt = art;
if(!art) if(!art)
{ {
image->disable();
text = std::string(); text = std::string();
hoverText = CGI->generaltexth->allTexts[507]; hoverText = CGI->generaltexth->allTexts[507];
} }
else else
{ {
image->enable();
image->setFrame(locked ? GameConstants::ID_LOCK : art->artType->iconIndex);
text = ourArt->artType->Description(); text = ourArt->artType->Description();
if(art->artType->id == 1) //spell scroll if(art->artType->id == 1) //spell scroll
{ {
@ -4529,7 +4583,7 @@ void CArtifactsOfHero::markPossibleSlots(const CArtifactInstance* art)
{ {
BOOST_FOREACH(CArtifactsOfHero *aoh, commonInfo->participants) BOOST_FOREACH(CArtifactsOfHero *aoh, commonInfo->participants)
BOOST_FOREACH(CArtPlace *place, aoh->artWorn) BOOST_FOREACH(CArtPlace *place, aoh->artWorn)
place->marked = art->canBePutAt(ArtifactLocation(aoh->curHero, place->slotID), true); place->selectSlot(art->canBePutAt(ArtifactLocation(aoh->curHero, place->slotID), true));
safeRedraw(); safeRedraw();
} }
@ -4552,9 +4606,9 @@ void CArtifactsOfHero::unmarkSlots(bool withRedraw /*= true*/)
void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw /*= true*/) void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw /*= true*/)
{ {
BOOST_FOREACH(CArtPlace *place, artWorn) BOOST_FOREACH(CArtPlace *place, artWorn)
place->marked = false; place->selectSlot(false);
BOOST_FOREACH(CArtPlace *place, backpack) BOOST_FOREACH(CArtPlace *place, backpack)
place->marked = false; place->selectSlot(false);
if(withRedraw) if(withRedraw)
safeRedraw(); safeRedraw();
@ -4570,13 +4624,13 @@ void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, int slotID)
return; return;
} }
artPlace->picked = false; artPlace->pickSlot(false);
artPlace->slotID = slotID; artPlace->slotID = slotID;
if(const ArtSlotInfo *asi = curHero->getSlot(slotID)) if(const ArtSlotInfo *asi = curHero->getSlot(slotID))
{ {
artPlace->setArtifact(asi->artifact); artPlace->setArtifact(asi->artifact);
artPlace->locked = asi->locked; artPlace->lockSlot(asi->locked);
} }
else else
artPlace->setArtifact(NULL); artPlace->setArtifact(NULL);
@ -4587,7 +4641,7 @@ void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, int slotID)
*/ */
void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, int slotID) void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, int slotID)
{ {
artPlace->picked = false; artPlace->pickSlot(false);
artPlace->slotID = slotID; artPlace->slotID = slotID;
artPlace->setArtifact(NULL); artPlace->setArtifact(NULL);
} }
@ -4638,20 +4692,19 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart
pos += position; pos += position;
artWorn.resize(19); artWorn.resize(19);
std::vector<Rect> slotPos; std::vector<Point> slotPos;
slotPos += genRect(44,44,509,30), genRect(44,44,567,240), genRect(44,44,509,80), slotPos += Point(509,30), Point(567,240), Point(509,80),
genRect(44,44,383,68), genRect(44,44,564,183), genRect(44,44,509,130), Point(383,68), Point(564,183), Point(509,130),
genRect(44,44,431,68), genRect(44,44,610,183), genRect(44,44,515,295), Point(431,68), Point(610,183), Point(515,295),
genRect(44,44,383,143), genRect(44,44,399,194), genRect(44,44,415,245), Point(383,143), Point(399,194), Point(415,245),
genRect(44,44,431,296), genRect(44,44,564,30), genRect(44,44,610,30), Point(431,296), Point(564,30), Point(610,30),
genRect(44,44,610,76), genRect(44,44,610,122), genRect(44,44,610,310), Point(610,76), Point(610,122), Point(610,310),
genRect(44,44,381,296); Point(381,296);
// Create slots for worn artifacts. // Create slots for worn artifacts.
for (size_t g = 0; g < 19 ; g++) for (size_t g = 0; g < 19 ; g++)
{ {
artWorn[g] = new CArtPlace(NULL); artWorn[g] = new CArtPlace(slotPos[g]);
artWorn[g]->pos = slotPos[g] + pos;
artWorn[g]->ourOwner = this; artWorn[g]->ourOwner = this;
eraseSlotData(artWorn[g], g); eraseSlotData(artWorn[g], g);
} }
@ -4659,12 +4712,9 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart
// Create slots for the backpack. // Create slots for the backpack.
for(size_t s=0; s<5; ++s) for(size_t s=0; s<5; ++s)
{ {
CArtPlace * add = new CArtPlace(NULL); CArtPlace * add = new CArtPlace(Point(403 + 46 * s, 365));
add->ourOwner = this; add->ourOwner = this;
add->pos.x = pos.x + 403 + 46*s;
add->pos.y = pos.y + 365;
add->pos.h = add->pos.w = 44;
eraseSlotData(add, 19 + s); eraseSlotData(add, 19 + s);
backpack.push_back(add); backpack.push_back(add);
@ -4782,7 +4832,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
commonInfo->src.art = dst.getArt(); commonInfo->src.art = dst.getArt();
commonInfo->src.slotID = dst.slot; commonInfo->src.slotID = dst.slot;
assert(commonInfo->src.AOH); assert(commonInfo->src.AOH);
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[dst.getArt()->artType->id].bitmap); CCS->curh->dragAndDropCursor(new CAnimImage("artifact", dst.getArt()->artType->iconIndex));
markPossibleSlots(dst.getArt()); markPossibleSlots(dst.getArt());
} }
} }
@ -5272,7 +5322,7 @@ int CUniversityWindow::CItem::state()
return 1; return 1;
if (parent->hero->secSkills.size() >= GameConstants::SKILL_PER_HERO)//can't learn more skills if (parent->hero->secSkills.size() >= GameConstants::SKILL_PER_HERO)//can't learn more skills
return 0; return 0;
if (parent->hero->type->heroClass->proSec[ID]==0)//can't learn this skill (like necromancy for most of non-necros) if (parent->hero->type->heroClass->secSkillProbability[ID]==0)//can't learn this skill (like necromancy for most of non-necros)
return 0; return 0;
return 2; return 2;
} }

View File

@ -881,16 +881,26 @@ public:
/// Artifacts can be placed there. Gets shown at the hero window /// Artifacts can be placed there. Gets shown at the hero window
class CArtPlace: public LRClickableAreaWTextComp class CArtPlace: public LRClickableAreaWTextComp
{ {
public: CAnimImage *image;
int slotID; //Arts::EPOS enum + backpack starting from Arts::BACKPACK_START CAnimImage *selection;
void createImage();
public:
// consider these members as const - change them only with appropriate methods e.g. lockSlot()
bool locked;
bool picked; bool picked;
bool marked; bool marked;
bool locked;
CArtifactsOfHero * ourOwner;
const CArtifactInstance * ourArt;
CArtPlace(const CArtifactInstance * Art); //c-tor int slotID; //Arts::EPOS enum + backpack starting from Arts::BACKPACK_START
void lockSlot(bool on);
void pickSlot(bool on);
void selectSlot(bool on);
CArtifactsOfHero * ourOwner;
const CArtifactInstance * ourArt; // should be changed only with setArtifact()
CArtPlace(Point position, const CArtifactInstance * Art = NULL); //c-tor CArtPlace(Point position, const CArtifactInstance * Art = NULL); //c-tor
void clickLeft(tribool down, bool previousState); void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState); void clickRight(tribool down, bool previousState);

View File

@ -142,7 +142,6 @@ Graphics::Graphics()
tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF"); tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF");
tasks += GET_DEF(smi2,"TWCRPORT.DEF"); tasks += GET_DEF(smi2,"TWCRPORT.DEF");
tasks += GET_DEF_ESS(flags,"CREST58.DEF"); tasks += GET_DEF_ESS(flags,"CREST58.DEF");
tasks += GET_DEF_ESS(abils82,"SECSK82.DEF");
tasks += GET_DEF_ESS(spellscr,"SPELLSCR.DEF"); tasks += GET_DEF_ESS(spellscr,"SPELLSCR.DEF");
tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF"); tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF");

View File

@ -66,8 +66,6 @@ public:
std::vector< std::string > battleHeroes; //battleHeroes[hero type] - name of def that has hero animation for battle std::vector< std::string > battleHeroes; //battleHeroes[hero type] - name of def that has hero animation for battle
std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
//abilities
CDefEssential * abils82;
//spells //spells
CDefEssential *spellscr; //spell on the scroll 83x61 CDefEssential *spellscr; //spell on the scroll 83x61
//functions //functions

View File

@ -3,8 +3,8 @@
#include <SDL.h> #include <SDL.h>
#include "SDL_Extensions.h" #include "SDL_Extensions.h"
#include "../CGameInfo.h" #include "CAnimation.h"
#include "../CDefHandler.h" #include "UIFramework/CGuiHandler.h"
/* /*
* CCursorHandler.cpp, part of VCMI engine * CCursorHandler.cpp, part of VCMI engine
@ -20,31 +20,44 @@ extern SDL_Surface * screen;
void CCursorHandler::initCursor() void CCursorHandler::initCursor()
{ {
mode = number = xpos = ypos = 0; xpos = ypos = 0;
dndImage = NULL; type = ECursor::DEFAULT;
dndObject = nullptr;
help = CSDL_Ext::newSurface(40,40); help = CSDL_Ext::newSurface(40,40);
cursors.push_back(CDefHandler::giveDef("CRADVNTR.DEF"));
cursors.push_back(CDefHandler::giveDef("CRCOMBAT.DEF"));
cursors.push_back(CDefHandler::giveDef("CRDEFLT.DEF"));
cursors.push_back(CDefHandler::giveDef("CRSPELL.DEF"));
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
changeGraphic(ECursor::ADVENTURE, 0);
} }
void CCursorHandler::changeGraphic(const int & type, const int & no) void CCursorHandler::changeGraphic(ECursor::ECursorTypes type, int index)
{ {
mode = type; std::string cursorDefs[4] = { "CRADVNTR.DEF", "CRCOMBAT.DEF", "CRDEFLT.DEF", "CRSPELL.DEF" };
number = no;
if (type != this->type)
{
BLOCK_CAPTURING; // not used here
this->type = type;
this->frame = index;
delete currentCursor;
currentCursor = new CAnimImage(cursorDefs[int(type)], index);
}
if (frame != index)
{
frame = index;
currentCursor->setFrame(index);
}
} }
/** void CCursorHandler::dragAndDropCursor(CAnimImage * object)
* Replaces the cursor with a custom image.
*
* @param image Image to replace cursor with or NULL to use the normal
* cursor.
*/
void CCursorHandler::dragAndDropCursor(SDL_Surface* image)
{ {
dndImage = image; if (dndObject)
delete dndObject;
dndObject = object;
} }
void CCursorHandler::cursorMove(const int & x, const int & y) void CCursorHandler::cursorMove(const int & x, const int & y)
@ -52,31 +65,34 @@ void CCursorHandler::cursorMove(const int & x, const int & y)
xpos = x; xpos = x;
ypos = y; ypos = y;
} }
void CCursorHandler::draw1()
void CCursorHandler::drawWithScreenRestore()
{ {
if(!Show) return; if(!showing) return;
int x = xpos, y = ypos; int x = xpos, y = ypos;
shiftPos(x, y); shiftPos(x, y);
SDL_Rect temp_rect1 = genRect(40,40,x,y); SDL_Rect temp_rect1 = genRect(40,40,x,y);
SDL_Rect temp_rect2 = genRect(40,40,0,0); SDL_Rect temp_rect2 = genRect(40,40,0,0);
SDL_BlitSurface(screen, &temp_rect1, help, &temp_rect2); SDL_BlitSurface(screen, &temp_rect1, help, &temp_rect2);
// if (dndImage)
// blitAt(dndImage, x - dndImage->w/2, y - dndImage->h/2);
// else
// blitAt(cursors[mode]->ourImages[number].bitmap,x,y);
if (dndImage) { if (dndObject)
SDL_Rect temp_rect =genRect(40, 40, x - dndImage->w/2, y - dndImage->h/2); {
SDL_BlitSurface(dndImage, NULL, screen, &temp_rect); dndObject->moveTo(Point(x - dndObject->pos.w/2, y - dndObject->pos.h/2));
} else { dndObject->showAll(screen);
SDL_Rect temp_rect = genRect(40,40,x,y); }
SDL_BlitSurface(cursors[mode]->ourImages[number].bitmap, NULL, screen, &temp_rect); else
{
currentCursor->moveTo(Point(x,y));
currentCursor->showAll(screen);
} }
} }
void CCursorHandler::draw2()
void CCursorHandler::drawRestored()
{ {
if(!Show) return; if(!showing)
return;
int x = xpos, y = ypos; int x = xpos, y = ypos;
shiftPos(x, y); shiftPos(x, y);
@ -87,21 +103,21 @@ void CCursorHandler::draw2()
void CCursorHandler::draw(SDL_Surface *to) void CCursorHandler::draw(SDL_Surface *to)
{ {
SDL_Rect temp_rect = genRect(40, 40, xpos, ypos); currentCursor->moveTo(Point(xpos, ypos));
CSDL_Ext::blitSurface(cursors[mode]->ourImages[number].bitmap, 0, to, &temp_rect); currentCursor->showAll(screen);
} }
void CCursorHandler::shiftPos( int &x, int &y ) void CCursorHandler::shiftPos( int &x, int &y )
{ {
if((mode==1 && number!=6) || mode ==3) if(( type == ECursor::COMBAT && frame != ECursor::COMBAT_POINTER) || type == ECursor::SPELLBOOK)
{ {
x-=16; x-=16;
y-=16; y-=16;
// Properly align the melee attack cursors. // Properly align the melee attack cursors.
if (mode == 1) if (type == ECursor::COMBAT == 1)
{ {
switch (number) switch (frame)
{ {
case 7: // Bottom left case 7: // Bottom left
x -= 6; x -= 6;
@ -138,22 +154,22 @@ void CCursorHandler::shiftPos( int &x, int &y )
} }
} }
} }
else if(mode==0) else if(ECursor::ADVENTURE == 0)
{ {
if(number == 0); //to exclude if (frame == 0); //to exclude
else if(number == 2) else if(frame == 2)
{ {
x -= 12; x -= 12;
y -= 10; y -= 10;
} }
else if(number == 3) else if(frame == 3)
{ {
x -= 12; x -= 12;
y -= 12; y -= 12;
} }
else if(number < 27) else if(frame < 27)
{ {
int hlpNum = (number - 4)%6; int hlpNum = (frame - 4)%6;
if(hlpNum == 0) if(hlpNum == 0)
{ {
x -= 15; x -= 15;
@ -185,12 +201,12 @@ void CCursorHandler::shiftPos( int &x, int &y )
y -= 16; y -= 16;
} }
} }
else if(number == 41) else if(frame == 41)
{ {
x -= 14; x -= 14;
y -= 16; y -= 16;
} }
else if(number < 31 || number == 42) else if(frame < 31 || frame == 42)
{ {
x -= 20; x -= 20;
y -= 20; y -= 20;
@ -200,9 +216,8 @@ void CCursorHandler::shiftPos( int &x, int &y )
void CCursorHandler::centerCursor() void CCursorHandler::centerCursor()
{ {
SDL_Surface *cursor = this->cursors[mode]->ourImages[number].bitmap; this->xpos = (screen->w / 2.) - (currentCursor->pos.w / 2.);
this->xpos = (screen->w / 2.) - (cursor->w / 2.); this->ypos = (screen->h / 2.) - (currentCursor->pos.h / 2.);
this->ypos = (screen->h / 2.) - (cursor->h / 2.);
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
SDL_WarpMouse(this->xpos, this->ypos); SDL_WarpMouse(this->xpos, this->ypos);
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE); SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
@ -213,6 +228,6 @@ CCursorHandler::~CCursorHandler()
if(help) if(help)
SDL_FreeSurface(help); SDL_FreeSurface(help);
for(int g=0; g<cursors.size(); ++g) delete currentCursor;
delete cursors[g]; delete dndObject;
} }

View File

@ -1,9 +1,6 @@
#pragma once #pragma once
class CAnimImage;
struct SDL_Thread;
class CDefHandler;
struct SDL_Surface; struct SDL_Surface;
/* /*
@ -30,25 +27,48 @@ namespace ECursor
/// handles mouse cursor /// handles mouse cursor
class CCursorHandler class CCursorHandler
{ {
public:
int mode, number;
SDL_Surface * help; SDL_Surface * help;
SDL_Surface * dndImage; CAnimImage * currentCursor;
bool Show; CAnimImage * dndObject; //if set, overrides currentCursor
bool showing;
std::vector<CDefHandler*> cursors; public:
int xpos, ypos; //position of cursor /// position of cursor
void initCursor(); //inits cursorHandler - run only once, it's not memleak-proof (rev 1333) int xpos, ypos;
void cursorMove(const int & x, const int & y); //change cursor's positions to (x, y)
void changeGraphic(const int & type, const int & no); //changes cursor graphic for type type (0 - adventure, 1 - combat, 2 - default, 3 - spellbook) and frame no (not used for type 3) /// Current cursor
void dragAndDropCursor (SDL_Surface* image); // Replace cursor with a custom image. ECursor::ECursorTypes type;
void draw1(); size_t frame;
/// inits cursorHandler - run only once, it's not memleak-proof (rev 1333)
void initCursor();
/// changes cursor graphic for type type (0 - adventure, 1 - combat, 2 - default, 3 - spellbook) and frame index (not used for type 3)
void changeGraphic(ECursor::ECursorTypes type, int index);
/**
* Replaces the cursor with a custom image.
*
* @param image Image to replace cursor with or NULL to use the normal
* cursor. CursorHandler takes ownership of object
*/
void dragAndDropCursor (CAnimImage * image);
/// Draw cursor preserving original image below cursor
void drawWithScreenRestore();
/// Restore original image below cursor
void drawRestored();
/// Simple draw cursor
void draw(SDL_Surface *to); void draw(SDL_Surface *to);
void shiftPos( int &x, int &y ); void shiftPos( int &x, int &y );
void draw2(); void hide() { showing=0; };
void hide() { Show=0; }; void show() { showing=1; };
void show() { Show=1; };
/// change cursor's positions to (x, y)
void cursorMove(const int & x, const int & y);
/// Move cursor to screen center
void centerCursor(); void centerCursor();
~CCursorHandler(); ~CCursorHandler();
}; };

View File

@ -568,7 +568,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
//pick graphics of hero (or boat if hero is sailing) //pick graphics of hero (or boat if hero is sailing)
iv = (themp->boat) iv = (themp->boat)
? &graphics->boatAnims[themp->boat->subID]->ourImages ? &graphics->boatAnims[themp->boat->subID]->ourImages
: &graphics->heroAnims[themp->type->heroType]->ourImages; : &graphics->heroAnims[themp->type->heroClass->id]->ourImages;
//pick appropriate flag set //pick appropriate flag set
if(themp->boat) if(themp->boat)

File diff suppressed because it is too large Load Diff

View File

@ -310,6 +310,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
} }
CArtifact &nart = *art; CArtifact &nart = *art;
nart.id=i; nart.id=i;
nart.iconIndex=i;
nart.setName (parser.readString()); nart.setName (parser.readString());
nart.setEventText (events.readString()); nart.setEventText (events.readString());
events.endLine(); events.endLine();

View File

@ -403,7 +403,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
for(auto i=available.begin(); i!=available.end(); i++) for(auto i=available.begin(); i!=available.end(); i++)
{ {
if(pavailable.find(i->first)->second & 1<<player if(pavailable.find(i->first)->second & 1<<player
&& i->second->type->heroType/2 == town->typeID) && i->second->type->heroClass->faction == town->typeID)
{ {
pool.push_back(i->second); //get all available heroes pool.push_back(i->second); //get all available heroes
} }
@ -680,7 +680,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
cur->ID = ran.first; cur->ID = ran.first;
h->portrait = cur->subID = ran.second; h->portrait = cur->subID = ran.second;
h->type = VLC->heroh->heroes[ran.second]; h->type = VLC->heroh->heroes[ran.second];
h->randomizeArmy(h->type->heroType/2); h->randomizeArmy(h->type->heroClass->faction);
map->heroes.push_back(h); map->heroes.push_back(h);
return; //TODO: maybe we should do something with definfo? return; //TODO: maybe we should do something with definfo?
} }

View File

@ -35,6 +35,16 @@ public:
std::string readString(); std::string readString();
float readNumber(); float readNumber();
template <typename numeric>
std::vector<numeric> readNumArray(size_t size)
{
std::vector<numeric> ret;
ret.reserve(size);
while (size--)
ret.push_back(readNumber());
return ret;
}
/// returns true if next entry is empty /// returns true if next entry is empty
bool isNextEntryEmpty(); bool isNextEntryEmpty();

View File

@ -5,7 +5,7 @@
#include "Filesystem/CResourceLoader.h" #include "Filesystem/CResourceLoader.h"
#include "VCMI_Lib.h" #include "VCMI_Lib.h"
#include "JsonNode.h" #include "JsonNode.h"
#include "GameConstants.h" #include "StringConstants.h"
#include "BattleHex.h" #include "BattleHex.h"
#include "CModHandler.h" #include "CModHandler.h"
@ -21,7 +21,6 @@
CHeroClass::CHeroClass() CHeroClass::CHeroClass()
{ {
skillLimit = 8;
} }
CHeroClass::~CHeroClass() CHeroClass::~CHeroClass()
{ {
@ -33,12 +32,12 @@ int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks se
int totalProb = 0; int totalProb = 0;
for(std::set<int>::const_iterator i=possibles.begin(); i!=possibles.end(); i++) for(std::set<int>::const_iterator i=possibles.begin(); i!=possibles.end(); i++)
{ {
totalProb += proSec[*i]; totalProb += secSkillProbability[*i];
} }
int ran = rand()%totalProb; int ran = rand()%totalProb;
for(std::set<int>::const_iterator i=possibles.begin(); i!=possibles.end(); i++) for(std::set<int>::const_iterator i=possibles.begin(); i!=possibles.end(); i++)
{ {
ran -= proSec[*i]; ran -= secSkillProbability[*i];
if(ran<0) if(ran<0)
return *i; return *i;
} }
@ -47,7 +46,7 @@ int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks se
EAlignment::EAlignment CHeroClass::getAlignment() const EAlignment::EAlignment CHeroClass::getAlignment() const
{ {
return (EAlignment::EAlignment)alignment; return EAlignment::EAlignment(VLC->townh->factions[faction].alignment);
} }
std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
@ -83,18 +82,78 @@ bool CObstacleInfo::isAppropriate(int terrainType, int specialBattlefield /*= -1
return vstd::contains(allowedTerrains, terrainType); return vstd::contains(allowedTerrains, terrainType);
} }
void CHeroClassHandler::load()
{
CLegacyConfigParser parser("DATA/HCTRAITS.TXT");
parser.endLine(); // header
parser.endLine();
do
{
CHeroClass * hc = new CHeroClass;
hc->name = parser.readString();
hc->aggression = parser.readNumber();
hc->id = heroClasses.size();
hc->primarySkillInitial = parser.readNumArray<int>(GameConstants::PRIMARY_SKILLS);
hc->primarySkillLowLevel = parser.readNumArray<int>(GameConstants::PRIMARY_SKILLS);
hc->primarySkillHighLevel = parser.readNumArray<int>(GameConstants::PRIMARY_SKILLS);
hc->secSkillProbability = parser.readNumArray<int>(GameConstants::SKILL_QUANTITY);
for(int dd=0; dd<GameConstants::F_NUMBER; ++dd)
{
hc->selectionProbability[dd] = parser.readNumber();
}
VLC->modh->identifiers.requestIdentifier("faction." + ETownType::names[heroClasses.size()/2],
[=](si32 faction)
{
hc->faction = faction;
});
heroClasses.push_back(hc);
VLC->modh->identifiers.registerObject("heroClass." + GameConstants::HERO_CLASSES_NAMES[hc->id], hc->id);
}
while (parser.endLine() && !parser.isNextEntryEmpty());
}
void CHeroClassHandler::load(const JsonNode & classes)
{
//TODO
}
void CHeroClassHandler::loadClass(const JsonNode & heroClass)
{
//TODO
}
CHeroClassHandler::~CHeroClassHandler()
{
BOOST_FOREACH(auto heroClass, heroClasses)
{
delete heroClass.get();
}
}
CHeroHandler::~CHeroHandler() CHeroHandler::~CHeroHandler()
{ {
for (int i = 0; i < heroes.size(); i++) BOOST_FOREACH(auto hero, heroes)
heroes[i].dellNull(); delete hero.get();
for (int i = 0; i < heroClasses.size(); i++)
delete heroClasses[i];
} }
CHeroHandler::CHeroHandler() CHeroHandler::CHeroHandler()
{} {}
void CHeroHandler::load()
{
classes.load();
loadHeroes();
loadObstacles();
}
void CHeroHandler::loadObstacles() void CHeroHandler::loadObstacles()
{ {
auto loadObstacles = [](const JsonNode &node, bool absolute, std::map<int, CObstacleInfo> &out) auto loadObstacles = [](const JsonNode &node, bool absolute, std::map<int, CObstacleInfo> &out)
@ -154,20 +213,20 @@ void CHeroHandler::loadHeroes()
// Load heroes information // Load heroes information
const JsonNode config(ResourceID("config/heroes.json")); const JsonNode config(ResourceID("config/heroes.json"));
BOOST_FOREACH(const JsonNode &hero, config["heroes"].Vector()) { BOOST_FOREACH(const JsonNode &hero, config["heroes"].Vector()) {
int hid = hero["id"].Float();
CHero * currentHero = heroes[hero["id"].Float()];
const JsonNode *value; const JsonNode *value;
// sex: 0=male, 1=female // sex: 0=male, 1=female
heroes[hid]->sex = !!hero["female"].Bool(); currentHero->sex = !!hero["female"].Bool();
heroes[hid]->heroType = CHero::EHeroClasses((int)hero["class"].Float());
BOOST_FOREACH(const JsonNode &set, hero["skill_set"].Vector()) { BOOST_FOREACH(const JsonNode &set, hero["skill_set"].Vector()) {
heroes[hid]->secSkillsInit.push_back(std::make_pair(set["skill"].Float(), set["level"].Float())); currentHero->secSkillsInit.push_back(std::make_pair(set["skill"].Float(), set["level"].Float()));
} }
value = &hero["spell"]; value = &hero["spell"];
if (!value->isNull()) { if (!value->isNull()) {
heroes[hid]->startingSpell = value->Float(); currentHero->startingSpell = value->Float();
} }
BOOST_FOREACH(const JsonNode &specialty, hero["specialties"].Vector()) BOOST_FOREACH(const JsonNode &specialty, hero["specialties"].Vector())
@ -179,12 +238,17 @@ void CHeroHandler::loadHeroes()
dummy.subtype = specialty["subtype"].Float(); dummy.subtype = specialty["subtype"].Float();
dummy.additionalinfo = specialty["info"].Float(); dummy.additionalinfo = specialty["info"].Float();
heroes[hid]->spec.push_back(dummy); //put a copy of dummy currentHero->spec.push_back(dummy); //put a copy of dummy
} }
VLC->modh->identifiers.requestIdentifier("heroClass." + hero["class"].String(),
[=](si32 classID)
{
currentHero->heroClass = classes.heroClasses[classID];
});
} }
loadHeroClasses(); loadTerrains();
initHeroClasses();
expPerLevel.push_back(0); expPerLevel.push_back(0);
expPerLevel.push_back(1000); expPerLevel.push_back(1000);
expPerLevel.push_back(2000); expPerLevel.push_back(2000);
@ -232,61 +296,6 @@ void CHeroHandler::loadHeroes()
while (ballParser.endLine()); while (ballParser.endLine());
} }
void CHeroHandler::loadHeroClasses()
{
CLegacyConfigParser parser("DATA/HCTRAITS.TXT");
parser.endLine(); // header
parser.endLine();
do
{
CHeroClass * hc = new CHeroClass;
hc->alignment = heroClasses.size() / 6;
hc->name = parser.readString();
hc->aggression = parser.readNumber();
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
{
hc->initialPrimSkills[g] = parser.readNumber();
}
hc->primChance.resize(GameConstants::PRIMARY_SKILLS);
for(int x=0; x<GameConstants::PRIMARY_SKILLS; ++x)
{
hc->primChance[x].first = parser.readNumber();
}
for(int x=0; x<GameConstants::PRIMARY_SKILLS; ++x)
{
hc->primChance[x].second = parser.readNumber();
}
hc->proSec.resize(GameConstants::SKILL_QUANTITY);
for(int dd=0; dd<GameConstants::SKILL_QUANTITY; ++dd)
{
hc->proSec[dd] = parser.readNumber();
}
for(int dd=0; dd<GameConstants::F_NUMBER; ++dd)
{
hc->selectionProbability[dd] = parser.readNumber();
}
heroClasses.push_back(hc);
}
while (parser.endLine() && !parser.isNextEntryEmpty());
}
void CHeroHandler::initHeroClasses()
{
for(int gg=0; gg<heroes.size(); ++gg)
{
heroes[gg]->heroClass = heroClasses[heroes[gg]->heroType];
}
loadTerrains();
}
ui32 CHeroHandler::level (ui64 experience) const ui32 CHeroHandler::level (ui64 experience) const
{ {
int i; int i;

View File

@ -18,6 +18,7 @@ class CDefHandler;
class CGameInfo; class CGameInfo;
class CGHeroInstance; class CGHeroInstance;
struct BattleHex; struct BattleHex;
class JsonNode;
struct SSpecialtyInfo struct SSpecialtyInfo
{ si32 type; { si32 type;
@ -45,17 +46,12 @@ public:
} }
}; };
enum EHeroClasses {KNIGHT, CLERIC, RANGER, DRUID, ALCHEMIST, WIZARD,
DEMONIAC, HERETIC, DEATHKNIGHT, NECROMANCER, WARLOCK, OVERLORD,
BARBARIAN, BATTLEMAGE, BEASTMASTER, WITCH, PLANESWALKER, ELEMENTALIST};
std::string name; //name of hero std::string name; //name of hero
si32 ID; si32 ID;
InitialArmyStack initialArmy[3]; InitialArmyStack initialArmy[3];
CHeroClass * heroClass; 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) std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
std::vector<SSpecialtyInfo> spec; std::vector<SSpecialtyInfo> spec;
si32 startingSpell; //-1 if none si32 startingSpell; //-1 if none
@ -67,20 +63,25 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & name & ID & initialArmy & heroClass & heroType & secSkillsInit & spec & startingSpell & sex; h & name & ID & initialArmy & heroClass & secSkillsInit & spec & startingSpell & sex;
} }
}; };
class DLL_LINKAGE CHeroClass class DLL_LINKAGE CHeroClass
{ {
public: public:
ui8 alignment; std::string identifier;
ui32 skillLimit; //how many secondary skills can hero learn std::string name; // translatable
std::string name;
double aggression; double aggression;
int initialPrimSkills[GameConstants::PRIMARY_SKILLS]; //initial values of primary skills, uses PrimarySkill enum TFaction faction;
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 ui8 id;
std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order
std::vector<int> primarySkillInitial; // initial primary skills
std::vector<int> primarySkillLowLevel; // probability (%) of getting point of primary skill when getting level
std::vector<int> primarySkillHighLevel;// same for high levels (> 10)
std::vector<int> secSkillProbability; //probabilities of gaining secondary skills (out of 112), in id order
std::map<TFaction, int> selectionProbability; //probability of selection in towns std::map<TFaction, int> selectionProbability; //probability of selection in towns
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
@ -89,8 +90,10 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & skillLimit & name & aggression & initialPrimSkills & primChance h & identifier & name & faction & aggression;
& proSec & selectionProbability & alignment; h & primarySkillInitial & primarySkillLowLevel;
h & primarySkillHighLevel & secSkillProbability;
h & selectionProbability;
} }
EAlignment::EAlignment getAlignment() const; EAlignment::EAlignment getAlignment() const;
}; };
@ -116,14 +119,38 @@ struct DLL_LINKAGE CObstacleInfo
} }
}; };
class DLL_LINKAGE CHeroHandler class DLL_LINKAGE CHeroClassHandler
{ {
public: public:
std::vector< ConstTransitivePtr<CHero> > heroes; //changed from nodrze std::vector< ConstTransitivePtr<CHeroClass> > heroClasses;
std::vector<CHeroClass *> heroClasses;
/// load from H3 config
void load();
/// load any number of classes from json
void load(const JsonNode & classes);
/// load one class from json
void loadClass(const JsonNode & heroClass);
~CHeroClassHandler();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroClasses;
}
};
class DLL_LINKAGE CHeroHandler
{
std::vector<ui64> 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 std::vector<ui64> 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
//default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock; -1 means terrain is imapassable public:
CHeroClassHandler classes;
std::vector< ConstTransitivePtr<CHero> > heroes; //changed from nodrze
//default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock; -1 means terrain is imapassable
std::vector<int> terrCosts; std::vector<int> terrCosts;
struct SBallisticsLevelInfo struct SBallisticsLevelInfo
@ -147,9 +174,8 @@ public:
ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount
ui64 reqExp(ui32 level) const; //calculates experience required for given level ui64 reqExp(ui32 level) const; //calculates experience required for given level
void load();
void loadHeroes(); void loadHeroes();
void loadHeroClasses();
void initHeroClasses();
void loadTerrains(); void loadTerrains();
CHeroHandler(); //c-tor CHeroHandler(); //c-tor
~CHeroHandler(); //d-tor ~CHeroHandler(); //d-tor
@ -167,15 +193,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & heroClasses & heroes & expPerLevel & ballistics & terrCosts; h & classes & heroes & expPerLevel & ballistics & terrCosts;
h & obstacles & absoluteObstacles; h & obstacles & absoluteObstacles;
if(!h.saving)
{
//restore class pointers
for (int i=0; i<heroes.size(); i++)
{
heroes[i]->heroClass = heroClasses[heroes[i]->heroType];
}
}
} }
}; };

View File

@ -58,6 +58,7 @@ set(lib_HEADERS
CScriptingModule.h CScriptingModule.h
CStopWatch.h CStopWatch.h
GameConstants.h GameConstants.h
StringConstants.h
IGameEventsReceiver.h IGameEventsReceiver.h
int3.h int3.h
Interprocess.h Interprocess.h

View File

@ -725,7 +725,7 @@ void CGHeroInstance::initHero()
{ {
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g) for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
{ {
pushPrimSkill(static_cast<PrimarySkill::PrimarySkill>(g), type->heroClass->initialPrimSkills[g]); pushPrimSkill(static_cast<PrimarySkill::PrimarySkill>(g), type->heroClass->primarySkillInitial[g]);
} }
} }
if(secSkills.size() == 1 && secSkills[0] == std::pair<ui8,ui8>(-1, -1)) //set secondary skills to default if(secSkills.size() == 1 && secSkills[0] == std::pair<ui8,ui8>(-1, -1)) //set secondary skills to default
@ -753,7 +753,7 @@ void CGHeroInstance::initHero()
if (VLC->modh->modules.COMMANDERS) if (VLC->modh->modules.COMMANDERS)
{ {
commander = new CCommanderInstance (VLC->creh->factionCommanders[type->heroType / 2]); //hopefully it returns town type commander = new CCommanderInstance (VLC->creh->factionCommanders[type->heroClass->faction]);
commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders
} }

View File

@ -4,7 +4,7 @@
#include "VCMI_Lib.h" #include "VCMI_Lib.h"
#include "CGeneralTextHandler.h" #include "CGeneralTextHandler.h"
#include "JsonNode.h" #include "JsonNode.h"
#include "GameConstants.h" #include "StringConstants.h"
#include "CModHandler.h" #include "CModHandler.h"
#include "Filesystem/CResourceLoader.h" #include "Filesystem/CResourceLoader.h"
@ -508,20 +508,12 @@ void CTownHandler::load()
JsonNode legacyConfig; JsonNode legacyConfig;
loadLegacyData(legacyConfig); loadLegacyData(legacyConfig);
//hardcoded list of H3 factions. Should be only used to convert H3 configs
static const std::string factionName [GameConstants::F_NUMBER] =
{
"castle", "rampart", "tower",
"inferno", "necropolis", "dungeon",
"stronghold", "fortress", "conflux"
};
// semi-manually merge legacy config with towns json // semi-manually merge legacy config with towns json
for (size_t i=0; i< legacyConfig.Vector().size(); i++) for (size_t i=0; i< legacyConfig.Vector().size(); i++)
{ {
JsonNode & legacyFaction = legacyConfig.Vector()[i]; JsonNode & legacyFaction = legacyConfig.Vector()[i];
JsonNode & outputFaction = buildingsConf[factionName[i]]; JsonNode & outputFaction = buildingsConf[ETownType::names[i]];
if (outputFaction["name"].isNull()) if (outputFaction["name"].isNull())
outputFaction["name"] = legacyFaction["name"]; outputFaction["name"] = legacyFaction["name"];

View File

@ -148,8 +148,6 @@ public:
h & names & typeID & creatures & buildings & hordeLvl & mageLevel h & names & typeID & creatures & buildings & hordeLvl & mageLevel
& primaryRes & warMachine & clientInfo; & primaryRes & warMachine & clientInfo;
} }
friend class CTownHandler;
}; };
struct DLL_LINKAGE SPuzzleInfo struct DLL_LINKAGE SPuzzleInfo

View File

@ -84,17 +84,11 @@ namespace GameConstants
const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty
const ui16 BACKPACK_START = 19; const ui16 BACKPACK_START = 19;
const int ID_CATAPULT = 3, ID_LOCK = 145; const int ID_CATAPULT = 3, ID_SELECTION=144, ID_LOCK = 145;
const int TERRAIN_TYPES=10; const int TERRAIN_TYPES=10;
const std::string TERRAIN_NAMES [TERRAIN_TYPES] = {
"dirt", "sand", "grass", "snow", "swamp", "rough", "subterra", "lava", "water", "rock"
};
const int RESOURCE_QUANTITY=8; const int RESOURCE_QUANTITY=8;
const std::string RESOURCE_NAMES [RESOURCE_QUANTITY] = {
"wood", "mercury", "ore", "sulfur", "crystal", "gems", "gold", "mithril"
};
} }
// Enum declarations // Enum declarations
@ -117,8 +111,6 @@ namespace ELossConditionType
namespace EAlignment namespace EAlignment
{ {
enum EAlignment { GOOD, EVIL, NEUTRAL }; enum EAlignment { GOOD, EVIL, NEUTRAL };
const std::string names [3] = {"good", "evil", "neutral"}; //for parsing from config file
} }
namespace ETownType namespace ETownType

View File

@ -38,6 +38,9 @@ public:
virtual int limit(const BonusLimitationContext &context) const; //0 - accept bonus; 1 - drop bonus; 2 - delay (drops eventually) virtual int limit(const BonusLimitationContext &context) const; //0 - accept bonus; 1 - drop bonus; 2 - delay (drops eventually)
virtual int callNext(const BonusLimitationContext &context) const; virtual int callNext(const BonusLimitationContext &context) const;
virtual ~LimiterDecorator()
{}
}; };
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix(); #define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();

View File

@ -341,7 +341,7 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
{ {
cgh->getBonusLocalFirst(Selector::type(Bonus::PRIMARY_SKILL) && cgh->getBonusLocalFirst(Selector::type(Bonus::PRIMARY_SKILL) &&
Selector::subtype(g) && Selector::sourceType(Bonus::HERO_BASE_SKILL) )->val Selector::subtype(g) && Selector::sourceType(Bonus::HERO_BASE_SKILL) )->val
= cgh->type->heroClass->initialPrimSkills[g]; = cgh->type->heroClass->primarySkillInitial[g];
} }
} }
} }

View File

@ -1,6 +1,6 @@
#include "StdInc.h" #include "StdInc.h"
#include "ResourceSet.h" #include "ResourceSet.h"
#include "GameConstants.h" #include "StringConstants.h"
#include "JsonNode.h" #include "JsonNode.h"
Res::ResourceSet::ResourceSet() Res::ResourceSet::ResourceSet()

67
lib/StringConstants.h Normal file
View File

@ -0,0 +1,67 @@
#pragma once
#include "GameConstants.h"
/*
* GameConstants.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
///
/// String ID which are pointless to move to config file - these types are mostly hardcoded
///
namespace GameConstants
{
const std::string TERRAIN_NAMES [TERRAIN_TYPES] = {
"dirt", "sand", "grass", "snow", "swamp", "rough", "subterra", "lava", "water", "rock"
};
const std::string RESOURCE_NAMES [RESOURCE_QUANTITY] = {
"wood", "mercury", "ore", "sulfur", "crystal", "gems", "gold", "mithril"
};
const std::string HERO_CLASSES_NAMES [F_NUMBER * 2] = {
"knight", "cleric", "ranger", "druid", "alchemist", "wizard",
"demoniac", "heretic", "deathknight", "necromancer", "warlock", "overlord",
"barbarian", "battlemage", "beastmaster", "witch", "planeswalker", "elementalist"
};
}
namespace EAlignment
{
const std::string names [3] = {"good", "evil", "neutral"};
}
namespace PrimarySkill
{
const std::string names [GameConstants::PRIMARY_SKILLS] = { "attack", "defence", "spellpower", "knowledge" };
}
namespace SecondarySkill
{
const std::string names [GameConstants::SKILL_QUANTITY] =
{
"pathfinding", "archery", "logistics", "scouting", "diplomacy", // 5
"navigation", "leadership", "wisdom", "mysticism", "luck", // 10
"ballistics", "eagleEye", "necromancy", "estates", "fireMagic", // 15
"airMagic", "waterMagic", "earthMagic", "scholar", "tactics", // 20
"artillery", "learning", "offence", "armorer", "intelligence", // 25
"sorcery", "resistance", "firstAid"
};
}
namespace ETownType
{
const std::string names [GameConstants::F_NUMBER] =
{
"castle", "rampart", "tower",
"inferno", "necropolis", "dungeon",
"stronghold", "fortress", "conflux"
};
}

View File

@ -82,8 +82,7 @@ void LibClasses::init()
tlog0<<"\tGeneral text handler: "<<pomtime.getDiff()<<std::endl; tlog0<<"\tGeneral text handler: "<<pomtime.getDiff()<<std::endl;
heroh = new CHeroHandler; heroh = new CHeroHandler;
heroh->loadHeroes(); heroh->load();
heroh->loadObstacles();
tlog0 <<"\tHero handler: "<<pomtime.getDiff()<<std::endl; tlog0 <<"\tHero handler: "<<pomtime.getDiff()<<std::endl;
arth = new CArtHandler; arth = new CArtHandler;

View File

@ -215,10 +215,12 @@ void CGameHandler::levelUpHero(int ID)
//give prim skill //give prim skill
tlog5 << hero->name <<" got level "<<hero->level<<std::endl; tlog5 << hero->name <<" got level "<<hero->level<<std::endl;
int r = rand()%100, pom=0, x=0; int r = rand()%100, pom=0, x=0;
int std::pair<int,int>::*g = (hero->level>9) ? (&std::pair<int,int>::second) : (&std::pair<int,int>::first);
auto & skillChances = (hero->level>9) ? hero->type->heroClass->primarySkillLowLevel : hero->type->heroClass->primarySkillHighLevel;
for(;x<GameConstants::PRIMARY_SKILLS;x++) for(;x<GameConstants::PRIMARY_SKILLS;x++)
{ {
pom += hero->type->heroClass->primChance[x].*g; pom += skillChances[x];
if(r<pom) if(r<pom)
break; break;
} }
@ -257,14 +259,14 @@ void CGameHandler::levelUpHero(int ID)
hlu.skills.push_back(s); hlu.skills.push_back(s);
basicAndAdv.erase(s); basicAndAdv.erase(s);
} }
else if(none.size() && hero->secSkills.size() < hero->type->heroClass->skillLimit) else if(none.size() && hero->secSkills.size() < GameConstants::SKILL_PER_HERO)
{ {
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //give new skill hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //give new skill
none.erase(hlu.skills.back()); none.erase(hlu.skills.back());
} }
//second offered skill //second offered skill
if(none.size() && hero->secSkills.size() < hero->type->heroClass->skillLimit) //hero have free skill slot if(none.size() && hero->secSkills.size() < GameConstants::SKILL_PER_HERO) //hero have free skill slot
{ {
hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
} }
@ -1695,7 +1697,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
{ {
obj->onHeroLeave(h); obj->onHeroLeave(h);
} }
getTilesInRange(tmh.fowRevealed, h->getSightCenter()+(tmh.end-tmh.start), h->getSightRadious(), h->tempOwner, 1); this->getTilesInRange(tmh.fowRevealed, h->getSightCenter()+(tmh.end-tmh.start), h->getSightRadious(), h->tempOwner, 1);
}; };
auto applyWithResult = [&](TryMoveHero::EResult result) -> bool auto applyWithResult = [&](TryMoveHero::EResult result) -> bool
@ -3006,7 +3008,7 @@ bool CGameHandler::buySecSkill( const IMarket *m, const CGHeroInstance *h, int s
if (h->secSkills.size() >= GameConstants::SKILL_PER_HERO)//can't learn more skills if (h->secSkills.size() >= GameConstants::SKILL_PER_HERO)//can't learn more skills
COMPLAIN_RET("Hero can't learn any more skills"); COMPLAIN_RET("Hero can't learn any more skills");
if (h->type->heroClass->proSec[skill]==0)//can't learn this skill (like necromancy for most of non-necros) if (h->type->heroClass->secSkillProbability[skill]==0)//can't learn this skill (like necromancy for most of non-necros)
COMPLAIN_RET("The hero can't learn this skill!"); COMPLAIN_RET("The hero can't learn this skill!");
if(!vstd::contains(m->availableItemsIds(EMarketMode::RESOURCE_SKILL), skill)) if(!vstd::contains(m->availableItemsIds(EMarketMode::RESOURCE_SKILL), skill))