mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
- merged minimap.json into terrains.json
- removed no longer used fields from Graphics + portraits.json - work on pregame: - - new code for map options window icons + popups - - fixed bugs related to new towns - - less hardcoded magic numbers
This commit is contained in:
parent
730cbd930a
commit
1c5a4c669c
@ -163,6 +163,8 @@
|
||||
{ "frame" : 159, "file" : "HPS133Nc.bmp"},
|
||||
{ "frame" : 160, "file" : "HPS134Nc.bmp"},
|
||||
{ "frame" : 161, "file" : "HPS135Wi.bmp"},
|
||||
{ "frame" : 162, "file" : "HPS136Wi.bmp"}
|
||||
{ "frame" : 162, "file" : "HPS136Wi.bmp"},
|
||||
{ "frame" : 200, "file" : "HPSRAND1.bmp"}, //random hero
|
||||
{ "frame" : 201, "file" : "HPSRAND6.bmp"} //no hero
|
||||
]
|
||||
}
|
||||
|
7
Mods/vcmi/Sprites/itpa.json
Normal file
7
Mods/vcmi/Sprites/itpa.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"images" :
|
||||
[
|
||||
{ "frame" : 38, "file" : "HPSRAND0.bmp"},
|
||||
{ "frame" : 39, "file" : "HPSRAND5.bmp"}
|
||||
]
|
||||
}
|
@ -479,11 +479,17 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
|
||||
|
||||
const JsonNode config(ResourceID(from, EResType::TEXT));
|
||||
|
||||
BOOST_FOREACH(const JsonNode &m, config["MinimapColors"].Vector())
|
||||
BOOST_FOREACH(auto &m, config.Struct())
|
||||
{
|
||||
int id = m["terrain_id"].Float();
|
||||
auto index = boost::find(GameConstants::TERRAIN_NAMES, m.first);
|
||||
if (index == boost::end(GameConstants::TERRAIN_NAMES))
|
||||
{
|
||||
tlog1 << "Error: unknown terrain in terrains.json: " << m.first << "\n";
|
||||
continue;
|
||||
}
|
||||
int terrainID = index - boost::begin(GameConstants::TERRAIN_NAMES);
|
||||
|
||||
const JsonVector &unblockedVec = m["unblocked"].Vector();
|
||||
const JsonVector &unblockedVec = m.second["minimapUnblocked"].Vector();
|
||||
SDL_Color normal =
|
||||
{
|
||||
ui8(unblockedVec[0].Float()),
|
||||
@ -492,7 +498,7 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
|
||||
ui8(255)
|
||||
};
|
||||
|
||||
const JsonVector &blockedVec = m["blocked"].Vector();
|
||||
const JsonVector &blockedVec = m.second["minimapBlocked"].Vector();
|
||||
SDL_Color blocked =
|
||||
{
|
||||
ui8(blockedVec[0].Float()),
|
||||
@ -501,7 +507,7 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
|
||||
ui8(255)
|
||||
};
|
||||
|
||||
ret.insert(std::make_pair(id, std::make_pair(normal, blocked)));
|
||||
ret.insert(std::make_pair(terrainID, std::make_pair(normal, blocked)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -511,7 +517,7 @@ CMinimap::CMinimap(const Rect &position):
|
||||
aiShield(nullptr),
|
||||
minimap(nullptr),
|
||||
level(0),
|
||||
colors(loadColors("config/minimap.json"))
|
||||
colors(loadColors("config/terrains.json"))
|
||||
{
|
||||
pos.w = position.w;
|
||||
pos.h = position.h;
|
||||
|
@ -67,7 +67,6 @@ public:
|
||||
void setFromLib();
|
||||
|
||||
friend class CClient;
|
||||
friend void initVillagesCapitols(CMap * map);
|
||||
|
||||
CGameInfo();
|
||||
};
|
||||
|
@ -173,11 +173,19 @@ void updateStartInfo(std::string filename, StartInfo & sInfo, const CMapHeader *
|
||||
pset.hero = pinfo.defaultHero();
|
||||
|
||||
|
||||
if(pinfo.mainHeroName.length())
|
||||
if(pinfo.customHeroID >= 0)
|
||||
{
|
||||
pset.heroName = pinfo.mainHeroName;
|
||||
if((pset.heroPortrait = pinfo.mainHeroPortrait) == 255)
|
||||
pset.heroPortrait = pinfo.p9;
|
||||
pset.hero = pinfo.customHeroID;
|
||||
|
||||
if (!pinfo.mainHeroName.empty())
|
||||
pset.heroName = pinfo.mainHeroName;
|
||||
else
|
||||
pset.heroName = CGI->heroh->heroes[pinfo.customHeroID]->name;
|
||||
|
||||
if (pinfo.mainHeroPortrait >= 0)
|
||||
pset.heroPortrait = pinfo.mainHeroPortrait;
|
||||
else
|
||||
pset.heroPortrait = pinfo.customHeroID;
|
||||
}
|
||||
pset.handicap = 0;
|
||||
}
|
||||
@ -470,21 +478,12 @@ void CGPreGame::loadGraphics()
|
||||
|
||||
victory = CDefHandler::giveDef("SCNRVICT.DEF");
|
||||
loss = CDefHandler::giveDef("SCNRLOSS.DEF");
|
||||
bonuses = CDefHandler::giveDef("SCNRSTAR.DEF");
|
||||
rHero = BitmapHandler::loadBitmap("HPSRAND1.bmp");
|
||||
rTown = BitmapHandler::loadBitmap("HPSRAND0.bmp");
|
||||
nHero = BitmapHandler::loadBitmap("HPSRAND6.bmp");
|
||||
nTown = BitmapHandler::loadBitmap("HPSRAND5.bmp");
|
||||
}
|
||||
|
||||
void CGPreGame::disposeGraphics()
|
||||
{
|
||||
delete victory;
|
||||
delete loss;
|
||||
SDL_FreeSurface(rHero);
|
||||
SDL_FreeSurface(nHero);
|
||||
SDL_FreeSurface(rTown);
|
||||
SDL_FreeSurface(nTown);
|
||||
}
|
||||
|
||||
void CGPreGame::update()
|
||||
@ -2247,10 +2246,10 @@ void OptionsTab::nextCastle( int player, int dir )
|
||||
si16 &cur = s.castle;
|
||||
auto & allowed = SEL->current->mapHeader->players[s.color].allowedFactions;
|
||||
|
||||
if (cur == -2) //no castle - no change
|
||||
if (cur == PlayerSettings::NONE) //no change
|
||||
return;
|
||||
|
||||
if (cur == -1) //random => first/last available
|
||||
if (cur == PlayerSettings::RANDOM) //first/last available
|
||||
{
|
||||
if (dir > 0)
|
||||
cur = *allowed.begin(); //id of first town
|
||||
@ -2272,14 +2271,15 @@ void OptionsTab::nextCastle( int player, int dir )
|
||||
}
|
||||
}
|
||||
|
||||
if(s.hero >= 0)
|
||||
s.hero = -1;
|
||||
if(s.hero >= 0 && SEL->current->mapHeader->players[s.color].customHeroID < 0) // remove hero unless it set to fixed one in map editor
|
||||
s.hero = PlayerSettings::RANDOM;
|
||||
if(cur < 0 && s.bonus == PlayerSettings::RESOURCE)
|
||||
s.bonus = PlayerSettings::RANDOM;
|
||||
|
||||
entries[player]->selectButtons();
|
||||
|
||||
SEL->propagateOptions();
|
||||
entries[player]->update();
|
||||
redraw();
|
||||
}
|
||||
|
||||
@ -2296,7 +2296,7 @@ void OptionsTab::nextHero( int player, int dir )
|
||||
if (s.castle < 0 || s.playerID == PlayerSettings::PLAYER_AI || s.hero == PlayerSettings::NONE)
|
||||
return;
|
||||
|
||||
if (s.hero == -1) //random => first/last available
|
||||
if (s.hero == PlayerSettings::RANDOM) // first/last available
|
||||
{
|
||||
int max = (s.castle*GameConstants::HEROES_PER_TYPE*2+15),
|
||||
min = (s.castle*GameConstants::HEROES_PER_TYPE*2);
|
||||
@ -2314,9 +2314,9 @@ void OptionsTab::nextHero( int player, int dir )
|
||||
{
|
||||
usedHeroes.erase(old);
|
||||
usedHeroes.insert(s.hero);
|
||||
entries[player]->update();
|
||||
redraw();
|
||||
}
|
||||
|
||||
SEL->propagateOptions();
|
||||
}
|
||||
|
||||
@ -2339,10 +2339,6 @@ int OptionsTab::nextAllowedHero( int min, int max, int incl, int dir )
|
||||
|
||||
bool OptionsTab::canUseThisHero( int ID )
|
||||
{
|
||||
//for(int i=0;i<CPG->ret.playerInfos.size();i++)
|
||||
// if(CPG->ret.playerInfos[i].hero==ID) //hero is already taken
|
||||
// return false;
|
||||
|
||||
return CGI->heroh->heroes.size() > ID
|
||||
&& !vstd::contains(usedHeroes, ID)
|
||||
&& SEL->current->mapHeader->allowedHeroes[ID];
|
||||
@ -2359,7 +2355,9 @@ void OptionsTab::nextBonus( int player, int dir )
|
||||
PlayerSettings &s = SEL->sInfo.playerInfos[player];
|
||||
si8 &ret = s.bonus += dir;
|
||||
|
||||
if (s.hero==-2 && !SEL->current->mapHeader->players[s.color].heroesNames.size() && ret==PlayerSettings::ARTIFACT) //no hero - can't be artifact
|
||||
if (s.hero==PlayerSettings::NONE &&
|
||||
!SEL->current->mapHeader->players[s.color].heroesNames.size() &&
|
||||
ret==PlayerSettings::ARTIFACT) //no hero - can't be artifact
|
||||
{
|
||||
if (dir<0)
|
||||
ret=PlayerSettings::RANDOM;
|
||||
@ -2371,7 +2369,7 @@ void OptionsTab::nextBonus( int player, int dir )
|
||||
if(ret < PlayerSettings::RANDOM)
|
||||
ret = PlayerSettings::RESOURCE;
|
||||
|
||||
if (s.castle==-1 && ret==PlayerSettings::RESOURCE) //random castle - can't be resource
|
||||
if (s.castle==PlayerSettings::RANDOM && ret==PlayerSettings::RESOURCE) //random castle - can't be resource
|
||||
{
|
||||
if (dir<0)
|
||||
ret=PlayerSettings::GOLD;
|
||||
@ -2379,6 +2377,7 @@ void OptionsTab::nextBonus( int player, int dir )
|
||||
}
|
||||
|
||||
SEL->propagateOptions();
|
||||
entries[player]->update();
|
||||
redraw();
|
||||
}
|
||||
|
||||
@ -2549,15 +2548,9 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
|
||||
else
|
||||
flag = NULL;
|
||||
|
||||
town = new SelectedBox(TOWN, s.color);
|
||||
town->pos.x += 119;
|
||||
town->pos.y += 2;
|
||||
hero = new SelectedBox(HERO, s.color);
|
||||
hero->pos.x += 195;
|
||||
hero->pos.y += 2;
|
||||
bonus = new SelectedBox(BONUS, s.color);
|
||||
bonus->pos.x += 271;
|
||||
bonus->pos.y += 2;
|
||||
town = new SelectedBox(Point(119, 2), s, TOWN);
|
||||
hero = new SelectedBox(Point(195, 2), s, HERO);
|
||||
bonus = new SelectedBox(Point(271, 2), s, BONUS);
|
||||
}
|
||||
|
||||
void OptionsTab::PlayerOptionsEntry::showAll(SDL_Surface * to)
|
||||
@ -2567,6 +2560,13 @@ void OptionsTab::PlayerOptionsEntry::showAll(SDL_Surface * to)
|
||||
printAtMiddleWBLoc(CGI->generaltexth->arraytxt[206+whoCanPlay], 28, 34, FONT_TINY, 8, Colors::WHITE, to);
|
||||
}
|
||||
|
||||
void OptionsTab::PlayerOptionsEntry::update()
|
||||
{
|
||||
town->update();
|
||||
hero->update();
|
||||
bonus->update();
|
||||
}
|
||||
|
||||
void OptionsTab::PlayerOptionsEntry::selectButtons()
|
||||
{
|
||||
if(!btns[0])
|
||||
@ -2608,299 +2608,312 @@ void OptionsTab::PlayerOptionsEntry::selectButtons()
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsTab::SelectedBox::showAll(SDL_Surface * to)
|
||||
{
|
||||
//PlayerSettings &s = SEL->sInfo.playerInfos[player];
|
||||
SDL_Surface *toBlit = getImg();
|
||||
const std::string *toPrint = getText();
|
||||
blitAt(toBlit, pos, to);
|
||||
printAtMiddleLoc(*toPrint, 23, 39, FONT_TINY, Colors::WHITE, to);
|
||||
}
|
||||
|
||||
OptionsTab::SelectedBox::SelectedBox( SelType Which, ui8 Player )
|
||||
:which(Which), player(Player)
|
||||
{
|
||||
SDL_Surface *img = getImg();
|
||||
pos.w = img->w;
|
||||
pos.h = img->h;
|
||||
addUsedEvents(RCLICK);
|
||||
}
|
||||
|
||||
size_t OptionsTab::SelectedBox::getBonusImageIndex() const
|
||||
size_t OptionsTab::CPlayerSettingsHelper::getImageIndex()
|
||||
{
|
||||
enum EBonusSelection //frames of bonuses file
|
||||
{
|
||||
WOOD_ORE = 0, CRYSTAL = 1, GEM = 2,
|
||||
MERCURY = 3, SULFUR = 5, GOLD = 8,
|
||||
ARTIFACT = 9, RANDOM = 10,
|
||||
WOOD = 0, ORE = 0, MITHRIL = 10 // resources unavailable in bonuses file
|
||||
WOOD = 0, ORE = 0, MITHRIL = 10, // resources unavailable in bonuses file
|
||||
|
||||
TOWN_RANDOM = 38, TOWN_NONE = 39, // Special frames in ITPA
|
||||
HERO_RANDOM = 200, HERO_NONE = 201 // Special frames in PortraitsSmall
|
||||
};
|
||||
|
||||
const PlayerSettings &s = SEL->sInfo.playerInfos[player];
|
||||
switch(s.bonus)
|
||||
{
|
||||
case -1: return RANDOM;
|
||||
case 0: return ARTIFACT;
|
||||
case 1: return GOLD;
|
||||
case 2:
|
||||
switch (CGI->townh->towns[s.castle].primaryRes)
|
||||
{
|
||||
case 127 : return WOOD_ORE;
|
||||
case Res::WOOD : return WOOD;
|
||||
case Res::MERCURY : return MERCURY;
|
||||
case Res::ORE : return ORE;
|
||||
case Res::SULFUR : return SULFUR;
|
||||
case Res::CRYSTAL : return CRYSTAL;
|
||||
case Res::GEMS : return GEM;
|
||||
case Res::GOLD : return GOLD;
|
||||
case Res::MITHRIL : return MITHRIL;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface * OptionsTab::SelectedBox::getImg() const
|
||||
{
|
||||
const PlayerSettings &s = SEL->sInfo.playerInfos[player];
|
||||
switch(which)
|
||||
switch(type)
|
||||
{
|
||||
case TOWN:
|
||||
if (s.castle == -1)
|
||||
return CGP->rTown;
|
||||
if (s.castle == -2)
|
||||
return CGP->nTown;
|
||||
else
|
||||
return graphics->getPic(s.castle, true, false);
|
||||
case HERO:
|
||||
if (s.hero == -1)
|
||||
switch (settings.castle)
|
||||
{
|
||||
return CGP->rHero;
|
||||
case PlayerSettings::NONE: return TOWN_NONE;
|
||||
case PlayerSettings::RANDOM: return TOWN_RANDOM;
|
||||
default: return CGI->townh->towns[settings.castle].clientInfo.icons[true][false] + 2;
|
||||
}
|
||||
else if (s.hero == -2)
|
||||
{
|
||||
if(s.heroPortrait >= 0)
|
||||
return graphics->portraitSmall[s.heroPortrait];
|
||||
else
|
||||
return CGP->nHero;
|
||||
}
|
||||
else
|
||||
{
|
||||
return graphics->portraitSmall[s.hero];
|
||||
}
|
||||
break;
|
||||
case BONUS:
|
||||
return CGP->bonuses->ourImages[getBonusImageIndex()].bitmap;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string * OptionsTab::SelectedBox::getText() const
|
||||
{
|
||||
const PlayerSettings &s = SEL->sInfo.playerInfos[player];
|
||||
switch(which)
|
||||
{
|
||||
case TOWN:
|
||||
if (s.castle == -1)
|
||||
return &CGI->generaltexth->allTexts[522];
|
||||
else if (s.castle == -2)
|
||||
return &CGI->generaltexth->allTexts[523];
|
||||
else
|
||||
return &CGI->townh->factions[s.castle].name;
|
||||
case HERO:
|
||||
if (s.hero == -1)
|
||||
return &CGI->generaltexth->allTexts[522];
|
||||
else if (s.hero == -2)
|
||||
switch (settings.hero)
|
||||
{
|
||||
if(s.heroPortrait >= 0)
|
||||
{
|
||||
if(s.heroName.length())
|
||||
return &s.heroName;
|
||||
else
|
||||
return &CGI->heroh->heroes[s.heroPortrait]->name;
|
||||
}
|
||||
else
|
||||
return &CGI->generaltexth->allTexts[523];
|
||||
}
|
||||
else
|
||||
{
|
||||
//if(s.heroName.length())
|
||||
// return &s.heroName;
|
||||
//else
|
||||
return &CGI->heroh->heroes[s.hero]->name;
|
||||
}
|
||||
case BONUS:
|
||||
switch (s.bonus)
|
||||
{
|
||||
case -1:
|
||||
return &CGI->generaltexth->allTexts[522];
|
||||
case PlayerSettings::NONE: return HERO_NONE;
|
||||
case PlayerSettings::RANDOM: return HERO_RANDOM;
|
||||
default:
|
||||
return &CGI->generaltexth->arraytxt[214 + s.bonus];
|
||||
{
|
||||
if(settings.heroPortrait >= 0)
|
||||
return settings.heroPortrait;
|
||||
return settings.hero;
|
||||
}
|
||||
}
|
||||
|
||||
case BONUS:
|
||||
{
|
||||
switch(settings.bonus)
|
||||
{
|
||||
case PlayerSettings::RANDOM: return RANDOM;
|
||||
case PlayerSettings::ARTIFACT: return ARTIFACT;
|
||||
case PlayerSettings::GOLD: return GOLD;
|
||||
case PlayerSettings::RESOURCE:
|
||||
{
|
||||
switch(CGI->townh->towns[settings.castle].primaryRes)
|
||||
{
|
||||
case 127 : return WOOD_ORE;
|
||||
case Res::WOOD : return WOOD;
|
||||
case Res::MERCURY : return MERCURY;
|
||||
case Res::ORE : return ORE;
|
||||
case Res::SULFUR : return SULFUR;
|
||||
case Res::CRYSTAL : return CRYSTAL;
|
||||
case Res::GEMS : return GEM;
|
||||
case Res::GOLD : return GOLD;
|
||||
case Res::MITHRIL : return MITHRIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string OptionsTab::CPlayerSettingsHelper::getImageName()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case OptionsTab::TOWN: return "ITPA";
|
||||
case OptionsTab::HERO: return "PortraitsSmall";
|
||||
case OptionsTab::BONUS: return "SCNRSTAR";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string OptionsTab::CPlayerSettingsHelper::getTitle()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case OptionsTab::TOWN: return (settings.castle < 0) ? CGI->generaltexth->allTexts[103] : CGI->generaltexth->allTexts[80];
|
||||
case OptionsTab::HERO: return (settings.hero < 0) ? CGI->generaltexth->allTexts[101] : CGI->generaltexth->allTexts[77];
|
||||
case OptionsTab::BONUS:
|
||||
{
|
||||
switch(settings.bonus)
|
||||
{
|
||||
case PlayerSettings::RANDOM: return CGI->generaltexth->allTexts[86]; //{Random Bonus}
|
||||
case PlayerSettings::ARTIFACT: return CGI->generaltexth->allTexts[83]; //{Artifact Bonus}
|
||||
case PlayerSettings::GOLD: return CGI->generaltexth->allTexts[84]; //{Gold Bonus}
|
||||
case PlayerSettings::RESOURCE: return CGI->generaltexth->allTexts[85]; //{Resource Bonus}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string OptionsTab::CPlayerSettingsHelper::getName()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TOWN:
|
||||
{
|
||||
switch (settings.castle)
|
||||
{
|
||||
case PlayerSettings::NONE : return CGI->generaltexth->allTexts[523];
|
||||
case PlayerSettings::RANDOM : return CGI->generaltexth->allTexts[522];
|
||||
default : return CGI->townh->factions[settings.castle].name;
|
||||
}
|
||||
}
|
||||
case HERO:
|
||||
{
|
||||
switch (settings.hero)
|
||||
{
|
||||
case PlayerSettings::NONE : return CGI->generaltexth->allTexts[523];
|
||||
case PlayerSettings::RANDOM : return CGI->generaltexth->allTexts[522];
|
||||
default :
|
||||
{
|
||||
if (!settings.heroName.empty())
|
||||
return settings.heroName;
|
||||
return CGI->heroh->heroes[settings.hero]->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
case BONUS:
|
||||
{
|
||||
switch (settings.bonus)
|
||||
{
|
||||
case PlayerSettings::RANDOM : return CGI->generaltexth->allTexts[522];
|
||||
default: return CGI->generaltexth->arraytxt[214 + settings.bonus];
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string OptionsTab::CPlayerSettingsHelper::getSubtitle()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TOWN: return getName();
|
||||
case HERO:
|
||||
{
|
||||
if (settings.hero >= 0)
|
||||
return getName() + " - " + CGI->heroh->heroes[settings.hero]->heroClass->name;
|
||||
return getName();
|
||||
}
|
||||
|
||||
case BONUS:
|
||||
{
|
||||
switch(settings.bonus)
|
||||
{
|
||||
case PlayerSettings::GOLD: return CGI->generaltexth->allTexts[87]; //500-1000
|
||||
case PlayerSettings::RESOURCE:
|
||||
{
|
||||
switch(CGI->townh->towns[settings.castle].primaryRes)
|
||||
{
|
||||
case Res::MERCURY: return CGI->generaltexth->allTexts[694];
|
||||
case Res::SULFUR: return CGI->generaltexth->allTexts[695];
|
||||
case Res::CRYSTAL: return CGI->generaltexth->allTexts[692];
|
||||
case Res::GEMS: return CGI->generaltexth->allTexts[693];
|
||||
case 127: return CGI->generaltexth->allTexts[89]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string OptionsTab::CPlayerSettingsHelper::getDescription()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TOWN: return CGI->generaltexth->allTexts[104];
|
||||
case HERO: return CGI->generaltexth->allTexts[102];
|
||||
case BONUS:
|
||||
{
|
||||
switch(settings.bonus)
|
||||
{
|
||||
case PlayerSettings::RANDOM: return CGI->generaltexth->allTexts[94]; //Gold, wood and ore, or an artifact is randomly chosen as your starting bonus
|
||||
case PlayerSettings::ARTIFACT: return CGI->generaltexth->allTexts[90]; //An artifact is randomly chosen and equipped to your starting hero
|
||||
case PlayerSettings::GOLD: return CGI->generaltexth->allTexts[92]; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool
|
||||
case PlayerSettings::RESOURCE:
|
||||
{
|
||||
switch(CGI->townh->towns[settings.castle].primaryRes)
|
||||
{
|
||||
case Res::MERCURY: return CGI->generaltexth->allTexts[690];
|
||||
case Res::SULFUR: return CGI->generaltexth->allTexts[691];
|
||||
case Res::CRYSTAL: return CGI->generaltexth->allTexts[688];
|
||||
case Res::GEMS: return CGI->generaltexth->allTexts[689];
|
||||
case 127: return CGI->generaltexth->allTexts[93]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
OptionsTab::CPregameTooltipBox::CPregameTooltipBox(CPlayerSettingsHelper & helper):
|
||||
CWindowObject(BORDERED | RCLICK_POPUP),
|
||||
CPlayerSettingsHelper(helper)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
||||
int value;
|
||||
|
||||
switch(CPlayerSettingsHelper::type)
|
||||
{
|
||||
break; case TOWN:
|
||||
value = settings.castle;
|
||||
break; case HERO:
|
||||
value = settings.hero;
|
||||
break; case BONUS:
|
||||
value = settings.bonus;
|
||||
}
|
||||
|
||||
if (value == PlayerSettings::RANDOM)
|
||||
genBonusWindow();
|
||||
else if (CPlayerSettingsHelper::type == BONUS)
|
||||
genBonusWindow();
|
||||
else if (CPlayerSettingsHelper::type == HERO)
|
||||
genHeroWindow();
|
||||
else if (CPlayerSettingsHelper::type == TOWN)
|
||||
genTownWindow();
|
||||
|
||||
center();
|
||||
}
|
||||
|
||||
void OptionsTab::CPregameTooltipBox::genHeader()
|
||||
{
|
||||
new CFilledTexture("DIBOXBCK", pos);
|
||||
updateShadow();
|
||||
|
||||
new CLabel(pos.w / 2 + 8, 21, FONT_MEDIUM, CENTER, Colors::YELLOW, getTitle());
|
||||
|
||||
new CLabel(pos.w / 2, 88, FONT_SMALL, CENTER, Colors::WHITE, getSubtitle());
|
||||
|
||||
new CAnimImage(getImageName(), getImageIndex(), 0, pos.w / 2 - 24, 45);
|
||||
}
|
||||
|
||||
void OptionsTab::CPregameTooltipBox::genTownWindow()
|
||||
{
|
||||
pos = Rect(0, 0, 228, 290);
|
||||
genHeader();
|
||||
|
||||
new CLabel(pos.w / 2 + 8, 122, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[79]);
|
||||
|
||||
std::vector<CComponent *> components;
|
||||
const CTown & town = CGI->townh->towns[settings.castle];
|
||||
|
||||
for (size_t i=0; i< town.creatures.size(); i++)
|
||||
components.push_back(new CComponent(CComponent::creature, town.creatures[i].front(), 0, CComponent::tiny));
|
||||
|
||||
new CComponentBox(components, Rect(0, 140, pos.w, 140));
|
||||
}
|
||||
|
||||
void OptionsTab::CPregameTooltipBox::genHeroWindow()
|
||||
{
|
||||
pos = Rect(0, 0, 292, 226);
|
||||
genHeader();
|
||||
|
||||
// speciality
|
||||
new CAnimImage("UN44", settings.hero, 0, pos.w / 2 - 22, 134);
|
||||
|
||||
new CLabel(pos.w / 2 + 4, 117, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[78]);
|
||||
new CLabel(pos.w / 2, 188, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->hTxts[settings.hero].bonusName);
|
||||
}
|
||||
|
||||
void OptionsTab::CPregameTooltipBox::genBonusWindow()
|
||||
{
|
||||
pos = Rect(0, 0, 228, 162);
|
||||
genHeader();
|
||||
|
||||
new CTextBox(getDescription(), Rect(10, 88, pos.w - 20, 70), 0, FONT_SMALL, CENTER, Colors::WHITE );
|
||||
}
|
||||
|
||||
OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings, SelType type)
|
||||
:CIntObject(RCLICK, position),
|
||||
CPlayerSettingsHelper(settings, type)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
||||
image = new CAnimImage(getImageName(), getImageIndex());
|
||||
subtitle = new CLabel(23, 39, FONT_TINY, CENTER, Colors::WHITE, getName());
|
||||
|
||||
pos = image->pos;
|
||||
}
|
||||
|
||||
void OptionsTab::SelectedBox::update()
|
||||
{
|
||||
image->setFrame(getImageIndex());
|
||||
subtitle->setTxt(getName());
|
||||
}
|
||||
|
||||
void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState )
|
||||
{
|
||||
if(indeterminate(down) || !down) return;
|
||||
const PlayerSettings &s = SEL->sInfo.playerInfos[player];
|
||||
SDL_Surface *bmp = NULL;
|
||||
const std::string *title = NULL, *subTitle = NULL;
|
||||
|
||||
subTitle = getText();
|
||||
|
||||
int val=-1;
|
||||
switch(which)
|
||||
if (down)
|
||||
{
|
||||
case TOWN:
|
||||
val = s.castle;
|
||||
break;
|
||||
case HERO:
|
||||
val = s.hero;
|
||||
if(val == -2) //none => we may have some preset info
|
||||
{
|
||||
int p9 = SEL->current->mapHeader->players[s.color].p9;
|
||||
if(p9 != 255 && SEL->sInfo.playerInfos[player].heroPortrait >= 0)
|
||||
val = p9;
|
||||
}
|
||||
break;
|
||||
case BONUS:
|
||||
val = s.bonus;
|
||||
break;
|
||||
// cases when we do not need to display a message
|
||||
if (settings.castle == -2 && CPlayerSettingsHelper::type == TOWN )
|
||||
return;
|
||||
if (settings.hero == -2 && SEL->current->mapHeader->players[settings.color].customHeroID == -1 && CPlayerSettingsHelper::type == HERO)
|
||||
return;
|
||||
|
||||
GH.pushInt(new CPregameTooltipBox(*this));
|
||||
}
|
||||
|
||||
if(val == -1 || which == BONUS) //random or bonus box
|
||||
{
|
||||
bmp = CMessage::drawDialogBox(256, 190);
|
||||
std::string *description = NULL;
|
||||
|
||||
switch(which)
|
||||
{
|
||||
case TOWN:
|
||||
title = &CGI->generaltexth->allTexts[103];
|
||||
description = &CGI->generaltexth->allTexts[104];
|
||||
break;
|
||||
case HERO:
|
||||
title = &CGI->generaltexth->allTexts[101];
|
||||
description = &CGI->generaltexth->allTexts[102];
|
||||
break;
|
||||
case BONUS:
|
||||
{
|
||||
switch(val)
|
||||
{
|
||||
case PlayerSettings::RANDOM:
|
||||
title = &CGI->generaltexth->allTexts[86]; //{Random Bonus}
|
||||
description = &CGI->generaltexth->allTexts[94]; //Gold, wood and ore, or an artifact is randomly chosen as your starting bonus
|
||||
break;
|
||||
case PlayerSettings::ARTIFACT:
|
||||
title = &CGI->generaltexth->allTexts[83]; //{Artifact Bonus}
|
||||
description = &CGI->generaltexth->allTexts[90]; //An artifact is randomly chosen and equipped to your starting hero
|
||||
break;
|
||||
case PlayerSettings::GOLD:
|
||||
title = &CGI->generaltexth->allTexts[84]; //{Gold Bonus}
|
||||
subTitle = &CGI->generaltexth->allTexts[87]; //500-1000
|
||||
description = &CGI->generaltexth->allTexts[92]; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool
|
||||
break;
|
||||
case PlayerSettings::RESOURCE:
|
||||
{
|
||||
title = &CGI->generaltexth->allTexts[85]; //{Resource Bonus}
|
||||
switch(CGI->townh->towns[s.castle].primaryRes)
|
||||
{
|
||||
case 1:
|
||||
subTitle = &CGI->generaltexth->allTexts[694];
|
||||
description = &CGI->generaltexth->allTexts[690];
|
||||
break;
|
||||
case 3:
|
||||
subTitle = &CGI->generaltexth->allTexts[695];
|
||||
description = &CGI->generaltexth->allTexts[691];
|
||||
break;
|
||||
case 4:
|
||||
subTitle = &CGI->generaltexth->allTexts[692];
|
||||
description = &CGI->generaltexth->allTexts[688];
|
||||
break;
|
||||
case 5:
|
||||
subTitle = &CGI->generaltexth->allTexts[693];
|
||||
description = &CGI->generaltexth->allTexts[689];
|
||||
break;
|
||||
case 127:
|
||||
subTitle = &CGI->generaltexth->allTexts[89]; //5-10 wood / 5-10 ore
|
||||
description = &CGI->generaltexth->allTexts[93]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(description)
|
||||
CSDL_Ext::printAtMiddleWB(*description, 125, 145, FONT_SMALL, 37, Colors::WHITE, bmp);
|
||||
}
|
||||
else if(val == -2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(which == TOWN)
|
||||
{
|
||||
bmp = CMessage::drawDialogBox(256, 319);
|
||||
title = &CGI->generaltexth->allTexts[80];
|
||||
|
||||
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[79], 135, 137, FONT_MEDIUM, Colors::YELLOW, bmp);
|
||||
|
||||
const CTown &t = CGI->townh->towns[val];
|
||||
//print creatures
|
||||
int x = 60, y = 159;
|
||||
for(int i = 0; i < 7; i++)
|
||||
{
|
||||
int c = t.creatures[i][0];
|
||||
blitAt(graphics->smallImgs[c], x, y, bmp);
|
||||
CSDL_Ext::printAtMiddleWB(CGI->creh->creatures[c]->nameSing, x + 16, y + 45, FONT_TINY, 10, Colors::WHITE, bmp);
|
||||
|
||||
if(i == 2)
|
||||
{
|
||||
x = 40;
|
||||
y += 76;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 52;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(val >= 0)
|
||||
{
|
||||
const CHero *h = CGI->heroh->heroes[val];
|
||||
bmp = CMessage::drawDialogBox(320, 255);
|
||||
title = &CGI->generaltexth->allTexts[77];
|
||||
|
||||
CSDL_Ext::printAtMiddle(*title, 167, 36, FONT_MEDIUM, Colors::YELLOW, bmp);
|
||||
CSDL_Ext::printAtMiddle(*subTitle + " - " + h->heroClass->name, 160, 99, FONT_SMALL, Colors::WHITE, bmp);
|
||||
|
||||
blitAt(getImg(), 136, 56, bmp);
|
||||
|
||||
//print specialty
|
||||
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[78], 166, 132, FONT_MEDIUM, Colors::YELLOW, bmp);
|
||||
blitAt(graphics->un44->ourImages[val].bitmap, 140, 150, bmp);
|
||||
CSDL_Ext::printAtMiddle(CGI->generaltexth->hTxts[val].bonusName, 166, 203, FONT_SMALL, Colors::WHITE, bmp);
|
||||
|
||||
GH.pushInt(new CInfoPopup(bmp, true));
|
||||
return;
|
||||
}
|
||||
|
||||
if(title)
|
||||
CSDL_Ext::printAtMiddle(*title, 135, 36, FONT_MEDIUM, Colors::YELLOW, bmp);
|
||||
if(subTitle)
|
||||
CSDL_Ext::printAtMiddle(*subTitle, 127, 103, FONT_SMALL, Colors::WHITE, bmp);
|
||||
|
||||
blitAt(getImg(), 104, 60, bmp);
|
||||
|
||||
GH.pushInt(new CInfoPopup(bmp, true));
|
||||
}
|
||||
|
||||
CScenarioInfo::CScenarioInfo(const CMapHeader *mapHeader, const StartInfo *startInfo)
|
||||
|
@ -192,18 +192,45 @@ class OptionsTab : public CIntObject
|
||||
public:
|
||||
enum SelType {TOWN, HERO, BONUS};
|
||||
|
||||
struct SelectedBox : public CIntObject //img with current town/hero/bonus
|
||||
struct CPlayerSettingsHelper
|
||||
{
|
||||
SelType which;
|
||||
ui8 player; //serial nr
|
||||
const PlayerSettings & settings;
|
||||
const SelType type;
|
||||
|
||||
size_t getBonusImageIndex() const;
|
||||
SDL_Surface *getImg() const;
|
||||
const std::string *getText() const;
|
||||
CPlayerSettingsHelper(const PlayerSettings & settings, SelType type):
|
||||
settings(settings),
|
||||
type(type)
|
||||
{}
|
||||
|
||||
SelectedBox(SelType Which, ui8 Player);
|
||||
void showAll(SDL_Surface * to);
|
||||
/// visible image settings
|
||||
size_t getImageIndex();
|
||||
std::string getImageName();
|
||||
|
||||
std::string getName(); /// name visible in options dialog
|
||||
std::string getTitle(); /// title in popup box
|
||||
std::string getSubtitle(); /// popup box subtitle
|
||||
std::string getDescription();/// popup box description, not always present
|
||||
};
|
||||
|
||||
class CPregameTooltipBox : public CWindowObject, public CPlayerSettingsHelper
|
||||
{
|
||||
void genHeader();
|
||||
void genTownWindow();
|
||||
void genHeroWindow();
|
||||
void genBonusWindow();
|
||||
public:
|
||||
CPregameTooltipBox(CPlayerSettingsHelper & helper);
|
||||
};
|
||||
|
||||
struct SelectedBox : public CIntObject, public CPlayerSettingsHelper //img with current town/hero/bonus
|
||||
{
|
||||
CAnimImage * image;
|
||||
CLabel *subtitle;
|
||||
|
||||
SelectedBox(Point position, PlayerSettings & settings, SelType type);
|
||||
void clickRight(tribool down, bool previousState);
|
||||
|
||||
void update();
|
||||
};
|
||||
|
||||
struct PlayerOptionsEntry : public CIntObject
|
||||
@ -221,6 +248,7 @@ public:
|
||||
PlayerOptionsEntry(OptionsTab *owner, PlayerSettings &S);
|
||||
void selectButtons(); //hides unavailable buttons
|
||||
void showAll(SDL_Surface * to);
|
||||
void update();
|
||||
};
|
||||
|
||||
CSlider *turnDuration;
|
||||
@ -645,8 +673,6 @@ public:
|
||||
|
||||
CMenuScreen* menu;
|
||||
|
||||
SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs
|
||||
CDefHandler *bonuses;
|
||||
CDefHandler *victory, *loss;
|
||||
|
||||
~CGPreGame();
|
||||
|
@ -811,13 +811,17 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
|
||||
pos.w = image->pos.w;
|
||||
pos.h = image->pos.h;
|
||||
|
||||
EFonts font = FONT_SMALL;
|
||||
if (imageSize < small)
|
||||
font = FONT_TINY; //other sizes?
|
||||
|
||||
pos.h += 4; //distance between text and image
|
||||
|
||||
std::vector<std::string> textLines = CMessage::breakText(getSubtitle(), std::max<int>(80, pos.w), FONT_SMALL);
|
||||
std::vector<std::string> textLines = CMessage::breakText(getSubtitle(), std::max<int>(80, pos.w), font);
|
||||
BOOST_FOREACH(auto & line, textLines)
|
||||
{
|
||||
int height = graphics->fonts[FONT_SMALL]->height;
|
||||
CLabel * label = new CLabel(pos.w/2, pos.h + height/2, FONT_SMALL, CENTER, Colors::WHITE, line);
|
||||
int height = graphics->fonts[font]->height;
|
||||
CLabel * label = new CLabel(pos.w/2, pos.h + height/2, font, CENTER, Colors::WHITE, line);
|
||||
|
||||
pos.h += height;
|
||||
if (label->pos.w > pos.w)
|
||||
@ -1035,7 +1039,7 @@ Point CComponentBox::getOrTextPos(CComponent *left, CComponent *right)
|
||||
|
||||
int CComponentBox::getDistance(CComponent *left, CComponent *right)
|
||||
{
|
||||
static const int betweenImagesMin = 50;
|
||||
static const int betweenImagesMin = 20;
|
||||
static const int betweenSubtitlesMin = 10;
|
||||
|
||||
int leftSubtitle = ( left->pos.w - left->image->pos.w) / 2;
|
||||
@ -4253,9 +4257,14 @@ void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState)
|
||||
|
||||
CHeroArea::CHeroArea(int x, int y, const CGHeroInstance * _hero):hero(_hero)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
pos.x += x; pos.w = 58;
|
||||
pos.y += y; pos.h = 64;
|
||||
|
||||
if (hero)
|
||||
new CAnimImage("PortraitsLarge", hero->portrait);
|
||||
}
|
||||
|
||||
void CHeroArea::clickLeft(tribool down, bool previousState)
|
||||
@ -4278,12 +4287,6 @@ void CHeroArea::hover(bool on)
|
||||
GH.statusbar->clear();
|
||||
}
|
||||
|
||||
void CHeroArea::showAll(SDL_Surface * to)
|
||||
{
|
||||
if (hero)
|
||||
blitAtLoc(graphics->portraitLarge[hero->portrait],0,0,to);
|
||||
}
|
||||
|
||||
void LRClickableAreaOpenTown::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if((!down) && previousState && town)
|
||||
|
@ -846,15 +846,14 @@ public:
|
||||
/// Opens hero window by left-clicking on it
|
||||
class CHeroArea: public CIntObject
|
||||
{
|
||||
public:
|
||||
const CGHeroInstance * hero;
|
||||
public:
|
||||
|
||||
CHeroArea(int x, int y, const CGHeroInstance * _hero);
|
||||
|
||||
void clickLeft(tribool down, bool previousState);
|
||||
void clickRight(tribool down, bool previousState);
|
||||
void hover(bool on);
|
||||
void showAll(SDL_Surface * to);
|
||||
};
|
||||
|
||||
/// Opens town screen by left-clicking on it
|
||||
|
@ -136,12 +136,9 @@ Graphics::Graphics()
|
||||
tasks += boost::bind(&Graphics::loadTrueType,this);
|
||||
tasks += boost::bind(&Graphics::loadPaletteAndColors,this);
|
||||
tasks += boost::bind(&Graphics::loadHeroFlags,this);
|
||||
tasks += boost::bind(&Graphics::loadHeroPortraits,this);
|
||||
tasks += boost::bind(&Graphics::initializeBattleGraphics,this);
|
||||
tasks += boost::bind(&Graphics::loadErmuToPicture,this);
|
||||
tasks += GET_DEF_ESS(artDefs,"ARTIFACT.DEF");
|
||||
tasks += GET_DEF_ESS(un44,"UN44.DEF");
|
||||
tasks += GET_DEF_ESS(smallIcons,"ITPA.DEF");
|
||||
tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF");
|
||||
tasks += GET_DEF(smi,"CPRSMALL.DEF");
|
||||
tasks += GET_DEF(smi2,"TWCRPORT.DEF");
|
||||
@ -175,31 +172,6 @@ Graphics::Graphics()
|
||||
bigImgs[71]->format->palette->colors[7] = green;
|
||||
delete smi2;
|
||||
}
|
||||
void Graphics::loadHeroPortraits()
|
||||
{
|
||||
const JsonNode config(ResourceID("config/portraits.json"));
|
||||
|
||||
BOOST_FOREACH(const JsonNode &portrait_node, config["hero_portrait"].Vector()) {
|
||||
std::string filename = portrait_node["filename"].String();
|
||||
|
||||
/* Small portrait. */
|
||||
portraitSmall.push_back(BitmapHandler::loadBitmap(filename));
|
||||
|
||||
/* Large portrait. Alter the filename. Size letter is usually
|
||||
* third one, but there are exceptions and it should fix the
|
||||
* problem. */
|
||||
for (int ff=0; ff<filename.size(); ++ff)
|
||||
{
|
||||
if (filename[ff]=='S') {
|
||||
filename[ff]='L';
|
||||
break;
|
||||
}
|
||||
}
|
||||
portraitLarge.push_back(BitmapHandler::loadBitmap(filename));
|
||||
|
||||
SDL_SetColorKey(portraitLarge[portraitLarge.size()-1],SDL_SRCCOLORKEY,SDL_MapRGB(portraitLarge[portraitLarge.size()-1]->format,0,255,255));
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::loadHeroAnims()
|
||||
{
|
||||
@ -334,23 +306,6 @@ void Graphics::loadHeroFlags()
|
||||
grupa.join_all();
|
||||
tlog0 << "Loading and transforming heroes' flags: "<<th.getDiff()<<std::endl;
|
||||
}
|
||||
SDL_Surface * Graphics::getPic(int ID, bool fort, bool builded)
|
||||
{
|
||||
if (ID==-1)
|
||||
return smallIcons->ourImages[0].bitmap;
|
||||
else if (ID==-2)
|
||||
return smallIcons->ourImages[1].bitmap;
|
||||
else if (ID==-3)
|
||||
return smallIcons->ourImages[2+GameConstants::F_NUMBER*4].bitmap;
|
||||
else
|
||||
{
|
||||
assert(vstd::contains(CGI->townh->towns, ID));
|
||||
int pom = CGI->townh->towns[ID].clientInfo.icons[fort][builded];
|
||||
if (smallIcons->ourImages.size() > pom + 2)
|
||||
return smallIcons->ourImages[pom + 2].bitmap;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
|
||||
{
|
||||
|
@ -45,11 +45,8 @@ public:
|
||||
SDL_Color * neutralColorPalette;
|
||||
|
||||
CDefEssential * artDefs; //artifacts //TODO: move to CArtifact class
|
||||
std::vector<SDL_Surface *> portraitSmall; //48x32 px portraits of heroes
|
||||
std::vector<SDL_Surface *> portraitLarge; //58x64 px portraits of heroes
|
||||
std::vector<CDefEssential *> flags1, flags2, flags3, flags4; //flags blitted on heroes when ,
|
||||
CDefEssential * un44; //many things
|
||||
CDefEssential * smallIcons, *resources32; //resources 32x32
|
||||
CDefEssential * resources32; //resources 32x32
|
||||
CDefEssential * flags;
|
||||
CDefEssential * heroMoveArrows;
|
||||
std::vector<CDefEssential *> heroAnims; // [class id: 0 - 17] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||
@ -82,9 +79,7 @@ public:
|
||||
void loadHeroFlags(std::pair<std::vector<CDefEssential *> Graphics::*, std::vector<const char *> > &pr, bool mode);
|
||||
void loadHeroAnims();
|
||||
void loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations, std::vector<CDefEssential *> Graphics::*dst);
|
||||
void loadHeroPortraits();
|
||||
void loadErmuToPicture();
|
||||
SDL_Surface * getPic(int ID, bool fort=true, bool builded=false); //returns small picture of town: ID=-1 - blank; -2 - border; -3 - random
|
||||
void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player
|
||||
void loadTrueType();
|
||||
void loadFonts();
|
||||
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"MinimapColors":
|
||||
// Colors of terrain in minimap, in RGB format
|
||||
[
|
||||
{ "name": "Dirt", "terrain_id": 0, "unblocked": [ 82, 56, 8 ], "blocked": [ 57, 40, 8 ] },
|
||||
{ "name": "Sand", "terrain_id": 1, "unblocked": [ 222, 207, 140 ], "blocked": [ 165, 158, 107 ] },
|
||||
{ "name": "Grass", "terrain_id": 2, "unblocked": [ 0, 65, 0 ], "blocked": [ 0, 48, 0 ] },
|
||||
{ "name": "Snow", "terrain_id": 3, "unblocked": [ 181, 199, 198 ], "blocked": [ 140, 158, 156 ] },
|
||||
{ "name": "Swamp", "terrain_id": 4, "unblocked": [ 74, 134, 107 ], "blocked": [ 33, 89, 66 ] },
|
||||
{ "name": "Rough", "terrain_id": 5, "unblocked": [ 132, 113, 49 ], "blocked": [ 99, 81, 33 ] },
|
||||
{ "name": "Subterranean", "terrain_id": 6, "unblocked": [ 132, 48, 0 ], "blocked": [ 90, 8, 0 ] },
|
||||
{ "name": "Lava", "terrain_id": 7, "unblocked": [ 74, 73, 74 ], "blocked": [ 41, 40, 41 ] },
|
||||
{ "name": "Water", "terrain_id": 8, "unblocked": [ 8, 81, 148 ], "blocked": [ 8, 81, 148 ] },
|
||||
{ "name": "Rock", "terrain_id": 9, "unblocked": [ 0, 0, 0 ], "blocked": [ 0, 0, 0 ] }
|
||||
]
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
// Heroes portraits
|
||||
{
|
||||
"hero_portrait" :
|
||||
[
|
||||
{ "id": 0, "filename": "HPS000KN.bmp" },
|
||||
{ "id": 1, "filename": "HPS001KN.bmp" },
|
||||
{ "id": 2, "filename": "HPS002KN.bmp" },
|
||||
{ "id": 3, "filename": "HPS003KN.bmp" },
|
||||
{ "id": 4, "filename": "HPS004KN.bmp" },
|
||||
{ "id": 5, "filename": "HPS005KN.bmp" },
|
||||
{ "id": 6, "filename": "HPS006KN.bmp" },
|
||||
{ "id": 7, "filename": "HPS007KN.bmp" },
|
||||
{ "id": 8, "filename": "HPS008CL.bmp" },
|
||||
{ "id": 9, "filename": "HPS009CL.bmp" },
|
||||
{ "id": 10, "filename": "HPS010CL.bmp" },
|
||||
{ "id": 11, "filename": "HPS011CL.bmp" },
|
||||
{ "id": 12, "filename": "HPS012CL.bmp" },
|
||||
{ "id": 13, "filename": "HPS013CL.bmp" },
|
||||
{ "id": 14, "filename": "HPS014CL.bmp" },
|
||||
{ "id": 15, "filename": "HPS015CL.bmp" },
|
||||
{ "id": 16, "filename": "HPS016RN.bmp" },
|
||||
{ "id": 17, "filename": "HPS017RN.bmp" },
|
||||
{ "id": 18, "filename": "HPS018RN.bmp" },
|
||||
{ "id": 19, "filename": "HPS019RN.bmp" },
|
||||
{ "id": 20, "filename": "HPS020RN.bmp" },
|
||||
{ "id": 21, "filename": "HPS021RN.bmp" },
|
||||
{ "id": 22, "filename": "HPS022RN.bmp" },
|
||||
{ "id": 23, "filename": "HPS023RN.bmp" },
|
||||
{ "id": 24, "filename": "HPS024DR.bmp" },
|
||||
{ "id": 25, "filename": "HPS025DR.bmp" },
|
||||
{ "id": 26, "filename": "HPS026DR.bmp" },
|
||||
{ "id": 27, "filename": "HPS027DR.bmp" },
|
||||
{ "id": 28, "filename": "HPS028DR.bmp" },
|
||||
{ "id": 29, "filename": "HPS029DR.bmp" },
|
||||
{ "id": 30, "filename": "HPS030DR.bmp" },
|
||||
{ "id": 31, "filename": "HPS031DR.bmp" },
|
||||
{ "id": 32, "filename": "HPS032AL.bmp" },
|
||||
{ "id": 33, "filename": "HPS033AL.bmp" },
|
||||
{ "id": 34, "filename": "HPS034AL.bmp" },
|
||||
{ "id": 35, "filename": "HPS035AL.bmp" },
|
||||
{ "id": 36, "filename": "HPS036AL.bmp" },
|
||||
{ "id": 37, "filename": "HPS037AL.bmp" },
|
||||
{ "id": 38, "filename": "HPS038AL.bmp" },
|
||||
{ "id": 39, "filename": "HPS039AL.bmp" },
|
||||
{ "id": 40, "filename": "HPS040WZ.bmp" },
|
||||
{ "id": 41, "filename": "HPS041WZ.bmp" },
|
||||
{ "id": 42, "filename": "HPS042WZ.bmp" },
|
||||
{ "id": 43, "filename": "HPS043WZ.bmp" },
|
||||
{ "id": 44, "filename": "HPS044WZ.bmp" },
|
||||
{ "id": 45, "filename": "HPS045WZ.bmp" },
|
||||
{ "id": 46, "filename": "HPS046WZ.bmp" },
|
||||
{ "id": 47, "filename": "HPS047WZ.bmp" },
|
||||
{ "id": 48, "filename": "HPS048HR.bmp" },
|
||||
{ "id": 49, "filename": "HPS049HR.bmp" },
|
||||
{ "id": 50, "filename": "HPS050HR.bmp" },
|
||||
{ "id": 51, "filename": "HPS051HR.bmp" },
|
||||
{ "id": 52, "filename": "HPS052HR.bmp" },
|
||||
{ "id": 53, "filename": "HPS053HR.bmp" },
|
||||
{ "id": 54, "filename": "HPS054HR.bmp" },
|
||||
{ "id": 55, "filename": "HPS055HR.bmp" },
|
||||
{ "id": 56, "filename": "HPS056DM.bmp" },
|
||||
{ "id": 57, "filename": "HPS057DM.bmp" },
|
||||
{ "id": 58, "filename": "HPS058DM.bmp" },
|
||||
{ "id": 59, "filename": "HPS059DM.bmp" },
|
||||
{ "id": 60, "filename": "HPS060DM.bmp" },
|
||||
{ "id": 61, "filename": "HPS061DM.bmp" },
|
||||
{ "id": 62, "filename": "HPS062DM.bmp" },
|
||||
{ "id": 63, "filename": "HPS063DM.bmp" },
|
||||
{ "id": 64, "filename": "HPS064DK.bmp" },
|
||||
{ "id": 65, "filename": "HPS065DK.bmp" },
|
||||
{ "id": 66, "filename": "HPS066DK.bmp" },
|
||||
{ "id": 67, "filename": "HPS067DK.bmp" },
|
||||
{ "id": 68, "filename": "HPS068DK.bmp" },
|
||||
{ "id": 69, "filename": "HPS069DK.bmp" },
|
||||
{ "id": 70, "filename": "HPS070DK.bmp" },
|
||||
{ "id": 71, "filename": "HPS071DK.bmp" },
|
||||
{ "id": 72, "filename": "HPS072NC.bmp" },
|
||||
{ "id": 73, "filename": "HPS073NC.bmp" },
|
||||
{ "id": 74, "filename": "HPS074NC.bmp" },
|
||||
{ "id": 75, "filename": "HPS075NC.bmp" },
|
||||
{ "id": 76, "filename": "HPS076NC.bmp" },
|
||||
{ "id": 77, "filename": "HPS077NC.bmp" },
|
||||
{ "id": 78, "filename": "HPS078NC.bmp" },
|
||||
{ "id": 79, "filename": "HPS079NC.bmp" },
|
||||
{ "id": 80, "filename": "HPS080OV.bmp" },
|
||||
{ "id": 81, "filename": "HPS081OV.bmp" },
|
||||
{ "id": 82, "filename": "HPS082OV.bmp" },
|
||||
{ "id": 83, "filename": "HPS083OV.bmp" },
|
||||
{ "id": 84, "filename": "HPS084OV.bmp" },
|
||||
{ "id": 85, "filename": "HPS085OV.bmp" },
|
||||
{ "id": 86, "filename": "HPS086OV.bmp" },
|
||||
{ "id": 87, "filename": "HPS087OV.bmp" },
|
||||
{ "id": 88, "filename": "HPS088WL.bmp" },
|
||||
{ "id": 89, "filename": "HPS089WL.bmp" },
|
||||
{ "id": 90, "filename": "HPS090WL.bmp" },
|
||||
{ "id": 91, "filename": "HPS091WL.bmp" },
|
||||
{ "id": 92, "filename": "HPS092WL.bmp" },
|
||||
{ "id": 93, "filename": "HPS093WL.bmp" },
|
||||
{ "id": 94, "filename": "HPS094WL.bmp" },
|
||||
{ "id": 95, "filename": "HPS095WL.bmp" },
|
||||
{ "id": 96, "filename": "HPS096BR.bmp" },
|
||||
{ "id": 97, "filename": "HPS097BR.bmp" },
|
||||
{ "id": 98, "filename": "HPS098BR.bmp" },
|
||||
{ "id": 99, "filename": "HPS099BR.bmp" },
|
||||
{ "id": 100, "filename": "HPS100BR.bmp" },
|
||||
{ "id": 101, "filename": "HPS101BR.bmp" },
|
||||
{ "id": 102, "filename": "HPS102BR.bmp" },
|
||||
{ "id": 103, "filename": "HPS103BR.bmp" },
|
||||
{ "id": 104, "filename": "HPS104BM.bmp" },
|
||||
{ "id": 105, "filename": "HPS105BM.bmp" },
|
||||
{ "id": 106, "filename": "HPS106BM.bmp" },
|
||||
{ "id": 107, "filename": "HPS107BM.bmp" },
|
||||
{ "id": 108, "filename": "HPS108BM.bmp" },
|
||||
{ "id": 109, "filename": "HPS109BM.bmp" },
|
||||
{ "id": 110, "filename": "HPS110BM.bmp" },
|
||||
{ "id": 111, "filename": "HPS111BM.bmp" },
|
||||
{ "id": 112, "filename": "HPS112BS.bmp" },
|
||||
{ "id": 113, "filename": "HPS113BS.bmp" },
|
||||
{ "id": 114, "filename": "HPS114BS.bmp" },
|
||||
{ "id": 115, "filename": "HPS115BS.bmp" },
|
||||
{ "id": 116, "filename": "HPS116BS.bmp" },
|
||||
{ "id": 117, "filename": "HPS117BS.bmp" },
|
||||
{ "id": 118, "filename": "HPS118BS.bmp" },
|
||||
{ "id": 119, "filename": "HPS119BS.bmp" },
|
||||
{ "id": 120, "filename": "HPS120WH.bmp" },
|
||||
{ "id": 121, "filename": "HPS121WH.bmp" },
|
||||
{ "id": 122, "filename": "HPS122WH.bmp" },
|
||||
{ "id": 123, "filename": "HPS123WH.bmp" },
|
||||
{ "id": 124, "filename": "HPS124WH.bmp" },
|
||||
{ "id": 125, "filename": "HPS125WH.bmp" },
|
||||
{ "id": 126, "filename": "HPS126WH.bmp" },
|
||||
{ "id": 127, "filename": "HPS127WH.bmp" },
|
||||
{ "id": 128, "filename": "HPS000PL.bmp" },
|
||||
{ "id": 129, "filename": "HPS001PL.bmp" },
|
||||
{ "id": 130, "filename": "HPS002PL.bmp" },
|
||||
{ "id": 131, "filename": "HPS003PL.bmp" },
|
||||
{ "id": 132, "filename": "HPS004PL.bmp" },
|
||||
{ "id": 133, "filename": "HPS005PL.bmp" },
|
||||
{ "id": 134, "filename": "HPS006PL.bmp" },
|
||||
{ "id": 135, "filename": "HPS007PL.bmp" },
|
||||
{ "id": 136, "filename": "HPS000EL.bmp" },
|
||||
{ "id": 137, "filename": "HPS001EL.bmp" },
|
||||
{ "id": 138, "filename": "HPS002EL.bmp" },
|
||||
{ "id": 139, "filename": "HPS003EL.bmp" },
|
||||
{ "id": 140, "filename": "HPS004EL.bmp" },
|
||||
{ "id": 141, "filename": "HPS005EL.bmp" },
|
||||
{ "id": 142, "filename": "HPS006EL.bmp" },
|
||||
{ "id": 143, "filename": "HPS007EL.bmp" },
|
||||
{ "id": 144, "filename": "HPS130KN.bmp" },
|
||||
{ "id": 145, "filename": "HPS000SH.bmp" },
|
||||
{ "id": 146, "filename": "HPS128QC.bmp" },
|
||||
{ "id": 147, "filename": "HPS003SH.bmp" },
|
||||
{ "id": 148, "filename": "HPS004SH.bmp" },
|
||||
{ "id": 149, "filename": "HPS005SH.bmp" },
|
||||
{ "id": 150, "filename": "HPS006SH.bmp" },
|
||||
{ "id": 151, "filename": "HPS007SH.bmp" },
|
||||
{ "id": 152, "filename": "HPS009SH.bmp" },
|
||||
{ "id": 153, "filename": "HPS008SH.bmp" },
|
||||
{ "id": 154, "filename": "HPS001SH.bmp" },
|
||||
{ "id": 155, "filename": "HPS131DM.bmp" },
|
||||
{ "id": 156, "filename": "HPS129MK.bmp" },
|
||||
{ "id": 157, "filename": "HPS002SH.bmp" },
|
||||
{ "id": 158, "filename": "HPS132Wl.bmp" },
|
||||
{ "id": 159, "filename": "HPS133Nc.bmp" },
|
||||
{ "id": 160, "filename": "HPS134Nc.bmp" },
|
||||
{ "id": 161, "filename": "HPS135Wi.bmp" },
|
||||
{ "id": 162, "filename": "HPS136Wi.bmp" }
|
||||
]
|
||||
}
|
@ -1,13 +1,62 @@
|
||||
{
|
||||
// Movement costs on different terrains
|
||||
"dirt" : 100,
|
||||
"sand" : 150,
|
||||
"grass" : 100,
|
||||
"snow" : 150,
|
||||
"swamp" : 175,
|
||||
"rough" : 125,
|
||||
"subterra" : 100,
|
||||
"lava" : 100,
|
||||
"water" : 100,
|
||||
"rock" : -1,
|
||||
"dirt" :
|
||||
{
|
||||
"moveCost" : 100,
|
||||
"minimapUnblocked" : [ 82, 56, 8 ],
|
||||
"minimapBlocked" : [ 57, 40, 8 ]
|
||||
},
|
||||
"sand" :
|
||||
{
|
||||
"moveCost" : 150,
|
||||
"minimapUnblocked" : [ 222, 207, 140 ],
|
||||
"minimapBlocked" : [ 165, 158, 107 ]
|
||||
},
|
||||
"grass" :
|
||||
{
|
||||
"moveCost" : 100,
|
||||
"minimapUnblocked" : [ 0, 65, 0 ],
|
||||
"minimapBlocked" : [ 0, 48, 0 ]
|
||||
},
|
||||
"snow" :
|
||||
{
|
||||
"moveCost" : 150,
|
||||
"minimapUnblocked" : [ 181, 199, 198 ],
|
||||
"minimapBlocked" : [ 140, 158, 156 ]
|
||||
},
|
||||
"swamp" :
|
||||
{
|
||||
"moveCost" : 175,
|
||||
"minimapUnblocked" : [ 74, 134, 107 ],
|
||||
"minimapBlocked" : [ 33, 89, 66 ]
|
||||
},
|
||||
"rough" :
|
||||
{
|
||||
"moveCost" : 125,
|
||||
"minimapUnblocked" : [ 132, 113, 49 ],
|
||||
"minimapBlocked" : [ 99, 81, 33 ]
|
||||
},
|
||||
"subterra" :
|
||||
{
|
||||
"moveCost" : 100,
|
||||
"minimapUnblocked" : [ 132, 48, 0 ],
|
||||
"minimapBlocked" : [ 90, 8, 0 ]
|
||||
},
|
||||
"lava" :
|
||||
{
|
||||
"moveCost" : 100,
|
||||
"minimapUnblocked" : [ 74, 73, 74 ],
|
||||
"minimapBlocked" : [ 41, 40, 41 ]
|
||||
},
|
||||
"water" :
|
||||
{
|
||||
"moveCost" : 100,
|
||||
"minimapUnblocked" : [ 8, 81, 148 ],
|
||||
"minimapBlocked" : [ 8, 81, 148 ]
|
||||
},
|
||||
"rock" :
|
||||
{
|
||||
"moveCost" : -1,
|
||||
"minimapUnblocked" : [ 0, 0, 0 ],
|
||||
"minimapBlocked" : [ 0, 0, 0 ]
|
||||
}
|
||||
}
|
||||
|
@ -468,6 +468,7 @@ CArtifact * CArtHandler::loadArtifact(const JsonNode & node)
|
||||
|
||||
int bearerType = -1;
|
||||
|
||||
// FIXME FIXME FIXME: value is unitialized = crash!
|
||||
auto it = artifactBearerMap.find (value->String());
|
||||
if (it != artifactPositionMap.end())
|
||||
{
|
||||
@ -487,9 +488,9 @@ CArtifact * CArtHandler::loadArtifact(const JsonNode & node)
|
||||
else
|
||||
tlog2 << "Warning! Artifact type " << value->String() << " not recognized!";
|
||||
|
||||
value = &node["slot"];
|
||||
if (!value->isNull() && bearerType == ArtBearer::HERO) //we assume non-hero slots are irrelevant?
|
||||
{
|
||||
value = &node["slot"];
|
||||
if (!value->isNull() && bearerType == ArtBearer::HERO) //we assume non-hero slots are irrelevant?
|
||||
{
|
||||
auto it = artifactPositionMap.find (value->String());
|
||||
if (it != artifactPositionMap.end())
|
||||
{
|
||||
|
@ -326,7 +326,7 @@ void CHeroHandler::loadTerrains()
|
||||
|
||||
terrCosts.reserve(GameConstants::TERRAIN_TYPES);
|
||||
BOOST_FOREACH(const std::string & name, GameConstants::TERRAIN_NAMES)
|
||||
terrCosts.push_back(config[name].Float());
|
||||
terrCosts.push_back(config[name]["moveCost"].Float());
|
||||
}
|
||||
|
||||
std::vector<ui8> CHeroHandler::getDefaultAllowedHeroes() const
|
||||
|
@ -13,8 +13,8 @@ SHeroName::SHeroName() : heroId(-1)
|
||||
}
|
||||
|
||||
PlayerInfo::PlayerInfo(): canHumanPlay(false), canComputerPlay(false),
|
||||
aiTactic(EAiTactic::RANDOM), isFactionRandom(false), mainHeroPortrait(255), hasMainTown(true),
|
||||
generateHeroAtMainTown(true), team(255), generateHero(false), p7(0), p8(0), p9(0), powerPlaceholders(-1)
|
||||
aiTactic(EAiTactic::RANDOM), isFactionRandom(false), mainHeroPortrait(-1), hasMainTown(true),
|
||||
generateHeroAtMainTown(true), team(255), generateHero(false), p7(0), hasHero(false), customHeroID(-1), powerPlaceholders(-1)
|
||||
{
|
||||
allowedFactions = VLC->townh->getDefaultAllowedFactions();
|
||||
}
|
||||
@ -34,7 +34,7 @@ si8 PlayerInfo::defaultCastle() const
|
||||
si8 PlayerInfo::defaultHero() const
|
||||
{
|
||||
// we will generate hero in front of main town
|
||||
if((generateHeroAtMainTown && hasMainTown) || p8)
|
||||
if((generateHeroAtMainTown && hasMainTown) || hasHero)
|
||||
{
|
||||
//random hero
|
||||
return -1;
|
||||
|
@ -107,8 +107,8 @@ struct DLL_LINKAGE PlayerInfo
|
||||
/** Unused. True if the faction should be chosen randomly. */
|
||||
bool isFactionRandom;
|
||||
|
||||
/** Specifies the ID of the main hero with chosen portrait. The default value is 255. */
|
||||
ui32 mainHeroPortrait;
|
||||
/** Specifies the ID of the main hero with chosen portrait. The default value is -1. */
|
||||
si32 mainHeroPortrait;
|
||||
|
||||
/** The name of the main hero. */
|
||||
std::string mainHeroName;
|
||||
@ -134,11 +134,11 @@ struct DLL_LINKAGE PlayerInfo
|
||||
/** Unknown and unused. */
|
||||
si32 p7;
|
||||
|
||||
/** TODO ? */
|
||||
si32 p8;
|
||||
/** Player has a (custom?) hero */
|
||||
bool hasHero;
|
||||
|
||||
/** TODO ? */
|
||||
si32 p9;
|
||||
/** ID of custom hero, -1 if none */
|
||||
si32 customHeroID;
|
||||
|
||||
/**
|
||||
* Unused. Count of hero placeholders containing hero type.
|
||||
@ -153,7 +153,7 @@ struct DLL_LINKAGE PlayerInfo
|
||||
template <typename Handler>
|
||||
void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & aiTactic & allowedFactions & isFactionRandom &
|
||||
h & p7 & hasHero & customHeroID & canHumanPlay & canComputerPlay & aiTactic & allowedFactions & isFactionRandom &
|
||||
mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
|
||||
posOfMainTown & team & generateHero;
|
||||
}
|
||||
|
@ -302,13 +302,19 @@ void CMapLoaderH3M::readPlayerInfo()
|
||||
mapHeader->players[i].posOfMainTown.z = buffer[pos++];
|
||||
}
|
||||
|
||||
mapHeader->players[i].p8 = buffer[pos++];
|
||||
mapHeader->players[i].p9 = buffer[pos++];
|
||||
if(mapHeader->players[i].p9 != 0xff)
|
||||
mapHeader->players[i].hasHero = buffer[pos++];
|
||||
mapHeader->players[i].customHeroID = buffer[pos++];
|
||||
|
||||
if(mapHeader->players[i].customHeroID != 0xff)
|
||||
{
|
||||
mapHeader->players[i].mainHeroPortrait = buffer[pos++];
|
||||
if (mapHeader->players[i].mainHeroPortrait == 0xff)
|
||||
mapHeader->players[i].mainHeroPortrait = -1; //correct 1-byte -1 (0xff) into 4-byte -1
|
||||
|
||||
mapHeader->players[i].mainHeroName = readString(buffer, pos);
|
||||
}
|
||||
else
|
||||
mapHeader->players[i].customHeroID = -1; //correct 1-byte -1 (0xff) into 4-byte -1
|
||||
|
||||
if(mapHeader->version != EMapFormat::ROE)
|
||||
{
|
||||
|
@ -60,8 +60,8 @@ struct PlayerSettings
|
||||
PlayerSettings()
|
||||
{
|
||||
bonus = RANDOM;
|
||||
castle = -2;
|
||||
heroPortrait = -1;
|
||||
castle = NONE;
|
||||
heroPortrait = RANDOM;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user