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

Merge pull request #222 from dydzio0614/HeroBattleWindow

Looks OK to me, thanks! :)
This commit is contained in:
DjWarmonger 2016-09-28 21:06:59 +02:00 committed by GitHub
commit e77d408e92
8 changed files with 134 additions and 16 deletions

View File

@ -177,6 +177,15 @@ void CBattleHero::setPhase(int newPhase)
nextPhase = 0;
}
void CBattleHero::hover(bool on)
{
//TODO: Make lines below work properly
if (on)
CCS->curh->changeGraphic(ECursor::COMBAT, 5);
else
CCS->curh->changeGraphic(ECursor::COMBAT, 0);
}
void CBattleHero::clickLeft(tribool down, bool previousState)
{
if(myOwner->spellDestSelectMode) //we are casting a spell
@ -196,6 +205,25 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
}
}
void CBattleHero::clickRight(tribool down, bool previousState)
{
Point windowPosition;
windowPosition.x = (!flip) ? myOwner->pos.topLeft().x + 1 : myOwner->pos.topRight().x - 79;
windowPosition.y = myOwner->pos.y + 135;
InfoAboutHero targetHero;
if (down && myOwner->myTurn)
{
if (myHero != nullptr)
targetHero.initFromHero(myHero, InfoAboutHero::EInfoLevel::INBATTLE);
else
targetHero = myOwner->enemyHero();
GH.pushInt(new CHeroInfoWindow(targetHero, &windowPosition));
}
}
void CBattleHero::switchToNextPhase()
{
if (phase != nextPhase)
@ -247,7 +275,7 @@ CBattleHero::CBattleHero(const std::string & defName, bool flipG, PlayerColor pl
CSDL_Ext::alphaTransform(elem.bitmap);
graphics->blueToPlayersAdv(elem.bitmap, player);
}
addUsedEvents(LCLICK);
addUsedEvents(LCLICK | RCLICK | HOVER);
switchToNextPhase();
}
@ -614,6 +642,47 @@ void CClickableHex::clickRight(tribool down, bool previousState)
}
}
CHeroInfoWindow::CHeroInfoWindow(const InfoAboutHero &hero, Point *position) : CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, "CHRPOP")
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
if (position != nullptr)
moveTo(*position);
background->colorize(hero.owner); //maybe add this functionality to base class?
int attack = hero.details->primskills[0];
int defense = hero.details->primskills[1];
int power = hero.details->primskills[2];
int knowledge = hero.details->primskills[3];
int morale = hero.details->morale;
int luck = hero.details->luck;
int currentSpellPoints = hero.details->mana;
int maxSpellPoints = hero.details->manaLimit;
new CAnimImage("PortraitsLarge", hero.portrait, 0, 10, 6);
//primary stats
new CLabel(9, 75, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[380] + ":");
new CLabel(9, 87, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[381] + ":");
new CLabel(9, 99, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[382] + ":");
new CLabel(9, 111, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[383] + ":");
new CLabel(69, 87, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(attack));
new CLabel(69, 99, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(defense));
new CLabel(69, 111, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(power));
new CLabel(69, 123, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(knowledge));
//morale+luck
new CLabel(9, 131, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[384] + ":");
new CLabel(9, 143, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[385] + ":");
new CAnimImage("IMRL22", morale + 3, 0, 47, 131);
new CAnimImage("ILCK22", luck + 3, 0, 47, 143);
//spell points
new CLabel(39, 174, EFonts::FONT_TINY, EAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[387]);
new CLabel(39, 186, EFonts::FONT_TINY, EAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints));
}
void CStackQueue::update()
{
stacksSorted.clear();

View File

@ -2,6 +2,7 @@
#include "../gui/CIntObject.h"
#include "../../lib/BattleHex.h"
#include "../windows/CWindowObject.h"
struct SDL_Surface;
class CDefHandler;
@ -62,11 +63,19 @@ public:
ui8 flagAnim, animCount; //for flag animation
void show(SDL_Surface * to) override; //prints next frame of animation to to
void setPhase(int newPhase); //sets phase of hero animation
void hover(bool on) override;
void clickLeft(tribool down, bool previousState) override; //call-in
void clickRight(tribool down, bool previousState) override; //call-in
CBattleHero(const std::string &defName, bool filpG, PlayerColor player, const CGHeroInstance *hero, const CBattleInterface *owner); //c-tor
~CBattleHero(); //d-tor
};
class CHeroInfoWindow : public CWindowObject
{
public:
CHeroInfoWindow(const InfoAboutHero &hero, Point *position);
};
/// Class which manages the battle options window
class CBattleOptionsWindow : public CIntObject
{

View File

@ -294,9 +294,9 @@ CHeroTooltip::CHeroTooltip(Point pos, const InfoAboutHero &hero):
}
CHeroTooltip::CHeroTooltip(Point pos, const CGHeroInstance * hero):
CArmyTooltip(pos, InfoAboutHero(hero, true))
CArmyTooltip(pos, InfoAboutHero(hero, InfoAboutHero::EInfoLevel::DETAILED))
{
init(InfoAboutHero(hero, true));
init(InfoAboutHero(hero, InfoAboutHero::EInfoLevel::DETAILED));
}
void CTownTooltip::init(const InfoAboutTown &town)

View File

@ -332,7 +332,8 @@ InfoAboutHero CBattleInfoEssentials::battleGetHeroInfo( ui8 side ) const
return InfoAboutHero();
}
return InfoAboutHero(hero, battleDoWeKnowAbout(side));
InfoAboutHero::EInfoLevel infoLevel = battleDoWeKnowAbout(side) ? InfoAboutHero::EInfoLevel::DETAILED : InfoAboutHero::EInfoLevel::BASIC;
return InfoAboutHero(hero, infoLevel);
}
int CBattleInfoEssentials::battleCastSpells(ui8 side) const
@ -424,6 +425,18 @@ ui8 CBattleInfoEssentials::playerToSide(PlayerColor player) const
return ret;
}
bool CBattleInfoEssentials::playerHasAccessToHeroInfo(PlayerColor player, const CGHeroInstance * h) const
{
RETURN_IF_NOT_BATTLE(false);
ui8 playerSide = playerToSide(player);
if (playerSide >= 0)
{
if (getBattle()->sides[!playerSide].hero == h)
return true;
}
return false;
}
ui8 CBattleInfoEssentials::battleGetSiegeLevel() const
{
RETURN_IF_NOT_BATTLE(0);

View File

@ -190,6 +190,7 @@ public:
bool battleCanFlee(PlayerColor player) const;
bool battleCanSurrender(PlayerColor player) const;
ui8 playerToSide(PlayerColor player) const;
bool playerHasAccessToHeroInfo(PlayerColor player, const CGHeroInstance * h) const;
ui8 battleGetSiegeLevel() const; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
bool battleHasHero(ui8 side) const;
int battleCastSpells(ui8 side) const; //how many spells has given side cast

View File

@ -271,19 +271,31 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
ERROR_RET_VAL_IF(!h, "That's not a hero!", false);
ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false);
bool accessFlag = hasAccess(h->tempOwner);
InfoAboutHero::EInfoLevel infoLevel = InfoAboutHero::EInfoLevel::BASIC;
if(!accessFlag && nullptr != selectedObject)
if(hasAccess(h->tempOwner))
infoLevel = InfoAboutHero::EInfoLevel::DETAILED;
if ( (infoLevel == InfoAboutHero::EInfoLevel::BASIC) && gs->curB) //if it's battle we can get enemy hero full data
{
if(gs->curB->playerHasAccessToHeroInfo(*player, h))
infoLevel = InfoAboutHero::EInfoLevel::INBATTLE;
}
if( (infoLevel == InfoAboutHero::EInfoLevel::BASIC) && nullptr != selectedObject)
{
const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);
if(nullptr != selectedHero)
accessFlag = selectedHero->hasVisions(hero, 1);
if(selectedHero->hasVisions(hero, 1))
infoLevel = InfoAboutHero::EInfoLevel::DETAILED;
}
dest.initFromHero(h, accessFlag);
dest.initFromHero(h, infoLevel);
//DISGUISED bonus implementation
bool disguiseFlag = (infoLevel == InfoAboutHero::EInfoLevel::DETAILED);
if(getPlayerRelations(getLocalPlayer(), hero->tempOwner) == PlayerRelations::ENEMIES)
{
//todo: bonus cashing
@ -312,7 +324,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
}
};
auto doAdvancedDisguise = [accessFlag, &doBasicDisguise](InfoAboutHero & info)
auto doAdvancedDisguise = [disguiseFlag, &doBasicDisguise](InfoAboutHero & info)
{
doBasicDisguise(info);

View File

@ -2619,7 +2619,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
continue;
const CGHeroInstance * best = statsHLP::findBestHero(this, g->second.color);
InfoAboutHero iah;
iah.initFromHero(best, level >= 2);
iah.initFromHero(best, (level >= 2) ? InfoAboutHero::EInfoLevel::DETAILED : InfoAboutHero::EInfoLevel::BASIC);
iah.army.clear();
tgi.colorToBestHero[g->second.color] = iah;
}
@ -3007,12 +3007,12 @@ InfoAboutHero::InfoAboutHero(const InfoAboutHero & iah):
assign(iah);
}
InfoAboutHero::InfoAboutHero(const CGHeroInstance *h, bool detailed)
InfoAboutHero::InfoAboutHero(const CGHeroInstance *h, InfoAboutHero::EInfoLevel infoLevel)
: details(nullptr),
hclass(nullptr),
portrait(-1)
{
initFromHero(h, detailed);
initFromHero(h, infoLevel);
}
InfoAboutHero::~InfoAboutHero()
@ -3026,11 +3026,13 @@ InfoAboutHero & InfoAboutHero::operator=(const InfoAboutHero & iah)
return *this;
}
void InfoAboutHero::initFromHero(const CGHeroInstance *h, bool detailed)
void InfoAboutHero::initFromHero(const CGHeroInstance *h, InfoAboutHero::EInfoLevel infoLevel)
{
if(!h)
return;
bool detailed = ( (infoLevel == EInfoLevel::DETAILED) || (infoLevel == EInfoLevel::INBATTLE) );
initFromArmy(h, detailed);
hclass = h->type->heroClass;
@ -3050,6 +3052,10 @@ void InfoAboutHero::initFromHero(const CGHeroInstance *h, bool detailed)
{
details->primskills[i] = h->getPrimSkillLevel(static_cast<PrimarySkill::PrimarySkill>(i));
}
if (infoLevel == EInfoLevel::INBATTLE)
details->manaLimit = h->manaLimit();
else
details->manaLimit = -1; //we do not want to leak max mana info outside battle so set to meaningless value
}
}

View File

@ -44,24 +44,32 @@ struct DLL_LINKAGE InfoAboutHero : public InfoAboutArmy
{
private:
void assign(const InfoAboutHero & iah);
public:
struct DLL_LINKAGE Details
{
std::vector<si32> primskills;
si32 mana, luck, morale;
si32 mana, manaLimit, luck, morale;
} *details;
const CHeroClass *hclass;
int portrait;
enum EInfoLevel
{
BASIC,
DETAILED,
INBATTLE
};
InfoAboutHero();
InfoAboutHero(const InfoAboutHero & iah);
InfoAboutHero(const CGHeroInstance *h, bool detailed);
InfoAboutHero(const CGHeroInstance *h, EInfoLevel infoLevel);
~InfoAboutHero();
InfoAboutHero & operator=(const InfoAboutHero & iah);
void initFromHero(const CGHeroInstance *h, bool detailed);
void initFromHero(const CGHeroInstance *h, EInfoLevel infoLevel);
};
/// Struct which holds a int information about a town