mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge branch 'develop' of https://github.com/vcmi/vcmi into develop
This commit is contained in:
commit
a1b7c9d8d2
@ -16,11 +16,11 @@ sudo apt-get update -qq
|
||||
|
||||
sudo apt-get install -qq $SUPPORT
|
||||
sudo apt-get install -qq $PACKAGE
|
||||
sudo apt-get install -qq cmake libboost1.54-all-dev zlib1g-dev
|
||||
sudo apt-get install -qq cmake ninja-build libboost1.54-all-dev zlib1g-dev
|
||||
sudo apt-get install -qq libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
|
||||
sudo apt-get install -qq libavformat-dev libswscale-dev
|
||||
sudo apt-get install -qq qt57declarative
|
||||
|
||||
#setup compiler
|
||||
source /opt/qt57/bin/qt57-env.sh
|
||||
export CC=${REAL_CC} CXX=${REAL_CXX}
|
||||
export CC=${REAL_CC} CXX=${REAL_CXX}
|
||||
|
10
.travis.yml
10
.travis.yml
@ -14,7 +14,7 @@ before_install:
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -G "Unix Makefiles" .. $VCMI_CMAKE_FLAGS
|
||||
- if [[ $TRAVIS_BRANCH != 'coverity_scan' ]]; then cmake -G "Unix Makefiles" .. $VCMI_CMAKE_FLAGS; fi
|
||||
|
||||
script:
|
||||
- test $TRAVIS_BRANCH != coverity_scan || exit 0
|
||||
@ -35,13 +35,13 @@ matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: VCMI_PLATFORM='linux' REAL_CC=clang-3.4 REAL_CXX=clang++-3.4 PACKAGE=clang-3.4 SUPPORT=libstdc++-4.8-dev
|
||||
env: VCMI_PLATFORM='linux' REAL_CC=clang-3.6 REAL_CXX=clang++-3.6 PACKAGE=clang-3.6 SUPPORT=libstdc++-4.8-dev
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: VCMI_PLATFORM='linux' REAL_CC=clang-3.5 REAL_CXX=clang++-3.5 PACKAGE=clang-3.5 SUPPORT=libstdc++-4.8-dev
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: VCMI_PLATFORM='linux' REAL_CC=clang-3.6 REAL_CXX=clang++-3.6 PACKAGE=clang-3.6 SUPPORT=libstdc++-4.8-dev
|
||||
env: VCMI_PLATFORM='linux' REAL_CC=clang-3.4 REAL_CXX=clang++-3.4 PACKAGE=clang-3.4 SUPPORT=libstdc++-4.8-dev
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: VCMI_PLATFORM='linux' REAL_CC=gcc-4.8 REAL_CXX=g++-4.8 PACKAGE=g++-4.8 SUPPORT=
|
||||
@ -57,8 +57,8 @@ addons:
|
||||
name: vcmi/vcmi
|
||||
description: Build submitted via Travis CI
|
||||
notification_email: coverity@arseniyshestakov.com
|
||||
build_command_prepend: cmake -G "Unix Makefiles" . -DENABLE_LAUNCHER=1 -DENABLE_TEST=1
|
||||
build_command: make
|
||||
build_command_prepend: "cov-configure --compiler clang-3.6 --comptype clangcc && cov-configure --comptype clangcxx --compiler clang++-3.6 && cmake -G Ninja .. -DCMAKE_BUILD_TYPE=DEBUG -DENABLE_LAUNCHER=1 -DENABLE_TEST=1"
|
||||
build_command: ninja -j 2
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
notifications:
|
||||
|
@ -13,30 +13,11 @@
|
||||
#include "EnemyInfo.h"
|
||||
#include "../../lib/spells/CSpellHandler.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//
|
||||
// //set has its own order, so remove_if won't work. TODO - reuse for map
|
||||
// template<typename Elem, typename Predicate>
|
||||
// void erase_if(std::set<Elem> &setContainer, Predicate pred)
|
||||
// {
|
||||
// auto itr = setContainer.begin();
|
||||
// auto endItr = setContainer.end();
|
||||
// while(itr != endItr)
|
||||
// {
|
||||
// auto tmpItr = itr++;
|
||||
// if(pred(*tmpItr))
|
||||
// setContainer.erase(tmpItr);
|
||||
// }
|
||||
// }
|
||||
*/
|
||||
|
||||
#define LOGL(text) print(text)
|
||||
#define LOGFL(text, formattingEl) print(boost::str(boost::format(text) % formattingEl))
|
||||
|
||||
CBattleAI::CBattleAI(void)
|
||||
: side(-1)
|
||||
: side(-1), wasWaitingForRealize(false), wasUnlockingGs(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -82,8 +63,8 @@ BattleAction CBattleAI::activeStack( const CStack * stack )
|
||||
return BattleAction::makeHeal(stack, woundHpToStack.rbegin()->second); //last element of the woundHpToStack is the most wounded stack
|
||||
}
|
||||
|
||||
if(cb->battleCanCastSpell())
|
||||
attemptCastingSpell();
|
||||
attemptCastingSpell();
|
||||
|
||||
if(auto ret = getCbc()->battleIsFinished())
|
||||
{
|
||||
//spellcast may finish battle
|
||||
@ -201,8 +182,14 @@ SpellTypes spellType(const CSpell *spell)
|
||||
|
||||
void CBattleAI::attemptCastingSpell()
|
||||
{
|
||||
auto hero = cb->battleGetMyHero();
|
||||
if(!hero)
|
||||
return;
|
||||
|
||||
if(!cb->battleCanCastSpell())
|
||||
return;
|
||||
|
||||
LOGL("Casting spells sounds like fun. Let's see...");
|
||||
auto hero = cb->battleGetMyHero(); //auto known = cb->battleGetFightingHero(side);
|
||||
//Get all spells we can cast
|
||||
std::vector<const CSpell*> possibleSpells;
|
||||
vstd::copy_if(VLC->spellh->objects, std::back_inserter(possibleSpells), [this] (const CSpell *s) -> bool
|
||||
|
@ -297,6 +297,7 @@ ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
return cre->getArmyStrength();
|
||||
}
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
{
|
||||
const CGDwelling *d = dynamic_cast<const CGDwelling*>(obj);
|
||||
return d->getArmyStrength();
|
||||
|
@ -83,6 +83,7 @@ struct SectorMap
|
||||
Sector()
|
||||
{
|
||||
id = -1;
|
||||
water = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,9 @@ CClientState * CCS = nullptr;
|
||||
|
||||
CGameInfo::CGameInfo()
|
||||
{
|
||||
generaltexth = nullptr;
|
||||
mh = nullptr;
|
||||
townh = nullptr;
|
||||
}
|
||||
|
||||
void CGameInfo::setFromLib()
|
||||
|
@ -70,7 +70,7 @@ namespace bfs = boost::filesystem;
|
||||
std::string NAME_AFFIX = "client";
|
||||
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
|
||||
CGuiHandler GH;
|
||||
static CClient *client=nullptr;
|
||||
static CClient *client = nullptr;
|
||||
|
||||
int preferredDriverIndex = -1;
|
||||
SDL_Window * mainWindow = nullptr;
|
||||
@ -619,17 +619,22 @@ void processCommand(const std::string &message)
|
||||
}
|
||||
else if(cn=="save")
|
||||
{
|
||||
if(!client)
|
||||
{
|
||||
std::cout << "Game in not active";
|
||||
return;
|
||||
}
|
||||
std::string fname;
|
||||
readed >> fname;
|
||||
client->save(fname);
|
||||
}
|
||||
else if(cn=="load")
|
||||
{
|
||||
// TODO: this code should end the running game and manage to call startGame instead
|
||||
std::string fname;
|
||||
readed >> fname;
|
||||
client->loadGame(fname);
|
||||
}
|
||||
// else if(cn=="load")
|
||||
// {
|
||||
// // TODO: this code should end the running game and manage to call startGame instead
|
||||
// std::string fname;
|
||||
// readed >> fname;
|
||||
// client->loadGame(fname);
|
||||
// }
|
||||
else if(message=="get txt")
|
||||
{
|
||||
std::cout << "Command accepted.\t";
|
||||
@ -667,11 +672,6 @@ void processCommand(const std::string &message)
|
||||
{
|
||||
vm.insert(std::pair<std::string, po::variable_value>("onlyAI", po::variable_value()));
|
||||
}
|
||||
else if (cn == "ai")
|
||||
{
|
||||
VLC->IS_AI_ENABLED = !VLC->IS_AI_ENABLED;
|
||||
std::cout << "Current AI status: " << (VLC->IS_AI_ENABLED ? "enabled" : "disabled") << std::endl;
|
||||
}
|
||||
else if(cn == "mp" && adventureInt)
|
||||
{
|
||||
if(const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(adventureInt->selection))
|
||||
@ -837,6 +837,11 @@ void processCommand(const std::string &message)
|
||||
else if(cn == "gosolo")
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||
if(!client)
|
||||
{
|
||||
std::cout << "Game in not active";
|
||||
return;
|
||||
}
|
||||
PlayerColor color;
|
||||
if(session["aiSolo"].Bool())
|
||||
{
|
||||
@ -871,6 +876,11 @@ void processCommand(const std::string &message)
|
||||
boost::to_lower(colorName);
|
||||
|
||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||
if(!client)
|
||||
{
|
||||
std::cout << "Game in not active";
|
||||
return;
|
||||
}
|
||||
PlayerColor color;
|
||||
if(LOCPLINT)
|
||||
color = LOCPLINT->playerID;
|
||||
@ -1250,7 +1260,7 @@ void startGame(StartInfo * options, CConnection *serv/* = nullptr*/)
|
||||
}
|
||||
}
|
||||
|
||||
client = new CClient;
|
||||
client = new CClient();
|
||||
CPlayerInterface::howManyPeople = 0;
|
||||
switch(options->mode) //new game
|
||||
{
|
||||
@ -1269,7 +1279,7 @@ void startGame(StartInfo * options, CConnection *serv/* = nullptr*/)
|
||||
break;
|
||||
}
|
||||
|
||||
client->connectionHandler = new boost::thread(&CClient::run, client);
|
||||
client->connectionHandler = new boost::thread(&CClient::run, client);
|
||||
}
|
||||
|
||||
void endGame()
|
||||
|
@ -87,7 +87,7 @@ CPlayerInterface * LOCPLINT;
|
||||
CBattleInterface * CPlayerInterface::battleInt;
|
||||
|
||||
enum EMoveState {STOP_MOVE, WAITING_MOVE, CONTINUE_MOVE, DURING_MOVE};
|
||||
CondSh<EMoveState> stillMoveHero; //used during hero movement
|
||||
CondSh<EMoveState> stillMoveHero(STOP_MOVE); //used during hero movement
|
||||
|
||||
int CPlayerInterface::howManyPeople = 0;
|
||||
|
||||
@ -1133,7 +1133,7 @@ void CPlayerInterface::showOkDialog(std::vector<Component> & components, const M
|
||||
CInfoWindow::showOkDialog(str, &intComps, onOk, true, playerID);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, int soundID, bool selection, bool cancel )
|
||||
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
waitWhileDialog();
|
||||
|
@ -164,7 +164,7 @@ public:
|
||||
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) override;
|
||||
void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) override;
|
||||
void showShipyardDialog(const IShipyard *obj) override; //obj may be town or shipyard;
|
||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override;
|
||||
void showPuzzleMap() override;
|
||||
|
@ -620,6 +620,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
|
||||
if (screenType == CMenuScreen::campaignList)
|
||||
{
|
||||
opt = nullptr;
|
||||
randMapTab = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2250,7 +2251,7 @@ void InfoCard::changeSelection( const CMapInfo *to )
|
||||
void InfoCard::clickRight( tribool down, bool previousState )
|
||||
{
|
||||
static const Rect flagArea(19, 397, 335, 23);
|
||||
if(down && SEL->current && isItInLoc(flagArea, GH.current->motion.x, GH.current->motion.y))
|
||||
if(SEL->current && down && SEL->current && isItInLoc(flagArea, GH.current->motion.x, GH.current->motion.y))
|
||||
showTeamsPopup();
|
||||
}
|
||||
|
||||
@ -3912,6 +3913,7 @@ CSavingScreen::~CSavingScreen()
|
||||
ISelectionScreenInfo::ISelectionScreenInfo(const std::map<ui8, std::string> *Names /*= nullptr*/)
|
||||
{
|
||||
multiPlayer = CMenuScreen::SINGLE_PLAYER;
|
||||
screenType = CMenuScreen::mainMenu;
|
||||
assert(!SEL);
|
||||
SEL = this;
|
||||
current = nullptr;
|
||||
@ -4102,6 +4104,8 @@ void StartWithCurrentSettings::apply(CSelectionScreen *selScreen)
|
||||
|
||||
CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode &config )
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
||||
pos.x += config["x"].Float();
|
||||
pos.y += config["y"].Float();
|
||||
pos.w = 200;
|
||||
@ -4110,24 +4114,23 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode &config )
|
||||
campFile = config["file"].String();
|
||||
video = config["video"].String();
|
||||
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
||||
status = config["open"].Bool() ? CCampaignScreen::ENABLED : CCampaignScreen::DISABLED;
|
||||
|
||||
CCampaignHeader header = CCampaignHandler::getHeader(campFile);
|
||||
hoverText = header.name;
|
||||
|
||||
hoverLabel = nullptr;
|
||||
if (status != CCampaignScreen::DISABLED)
|
||||
{
|
||||
addUsedEvents(LCLICK | HOVER);
|
||||
image = new CPicture(config["image"].String());
|
||||
new CPicture(config["image"].String());
|
||||
|
||||
hoverLabel = new CLabel(pos.w / 2, pos.h + 20, FONT_MEDIUM, CENTER, Colors::YELLOW, "");
|
||||
parent->addChild(hoverLabel);
|
||||
}
|
||||
|
||||
if (status == CCampaignScreen::COMPLETED)
|
||||
checkMark = new CPicture("CAMPCHK");
|
||||
new CPicture("CAMPCHK");
|
||||
}
|
||||
|
||||
void CCampaignScreen::CCampaignButton::clickLeft(tribool down, bool previousState)
|
||||
@ -4142,10 +4145,13 @@ void CCampaignScreen::CCampaignButton::clickLeft(tribool down, bool previousStat
|
||||
|
||||
void CCampaignScreen::CCampaignButton::hover(bool on)
|
||||
{
|
||||
if (on)
|
||||
hoverLabel->setText(hoverText); // Shows the name of the campaign when you get into the bounds of the button
|
||||
else
|
||||
hoverLabel->setText(" ");
|
||||
if (hoverLabel)
|
||||
{
|
||||
if (on)
|
||||
hoverLabel->setText(hoverText); // Shows the name of the campaign when you get into the bounds of the button
|
||||
else
|
||||
hoverLabel->setText(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void CCampaignScreen::CCampaignButton::show(SDL_Surface * to)
|
||||
@ -4198,7 +4204,7 @@ CCampaignScreen::CCampaignScreen(const JsonNode &config)
|
||||
|
||||
if (!config["exitbutton"].isNull())
|
||||
{
|
||||
back = createExitButton(config["exitbutton"]);
|
||||
CButton * back = createExitButton(config["exitbutton"]);
|
||||
back->hoverable = true;
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,6 @@ class InfoCard : public CIntObject
|
||||
std::shared_ptr<CAnimation> sFlags;
|
||||
public:
|
||||
CPicture *bg;
|
||||
CMenuScreen::EState type;
|
||||
|
||||
bool network;
|
||||
bool chatOn; //if chat is shown, then description is hidden
|
||||
@ -554,9 +553,6 @@ private:
|
||||
class CCampaignButton : public CIntObject
|
||||
{
|
||||
private:
|
||||
CPicture *image;
|
||||
CPicture *checkMark;
|
||||
|
||||
CLabel *hoverLabel;
|
||||
CampaignStatus status;
|
||||
|
||||
@ -572,7 +568,6 @@ private:
|
||||
void show(SDL_Surface * to) override;
|
||||
};
|
||||
|
||||
CButton *back;
|
||||
std::vector<CCampaignButton*> campButtons;
|
||||
std::vector<CPicture*> images;
|
||||
|
||||
|
@ -49,13 +49,20 @@ static si64 lodSeek(void * opaque, si64 pos, int whence)
|
||||
|
||||
CVideoPlayer::CVideoPlayer()
|
||||
{
|
||||
stream = -1;
|
||||
format = nullptr;
|
||||
frame = nullptr;
|
||||
codecContext = nullptr;
|
||||
codec = nullptr;
|
||||
frame = nullptr;
|
||||
sws = nullptr;
|
||||
context = nullptr;
|
||||
texture = nullptr;
|
||||
dest = nullptr;
|
||||
context = nullptr;
|
||||
destRect = genRect(0,0,0,0);
|
||||
pos = genRect(0,0,0,0);
|
||||
refreshWait = 0;
|
||||
refreshCount = 0;
|
||||
doLoop = false;
|
||||
|
||||
// Register codecs. TODO: May be overkill. Should call a
|
||||
// combination of av_register_input_format() /
|
||||
@ -143,17 +150,17 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
|
||||
}
|
||||
// Allocate video frame
|
||||
frame = av_frame_alloc();
|
||||
|
||||
|
||||
//setup scaling
|
||||
if(scale)
|
||||
{
|
||||
pos.w = screen->w;
|
||||
pos.w = screen->w;
|
||||
pos.h = screen->h;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.w = codecContext->width;
|
||||
pos.h = codecContext->height;
|
||||
pos.w = codecContext->width;
|
||||
pos.h = codecContext->height;
|
||||
}
|
||||
|
||||
// Allocate a place to put our YUV image on that screen
|
||||
@ -174,7 +181,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
|
||||
|
||||
if (texture)
|
||||
{ // Convert the image into YUV format that SDL uses
|
||||
sws = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt,
|
||||
sws = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt,
|
||||
pos.w, pos.h,
|
||||
AV_PIX_FMT_YUV420P,
|
||||
SWS_BICUBIC, nullptr, nullptr, nullptr);
|
||||
@ -205,8 +212,8 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
|
||||
}
|
||||
}
|
||||
|
||||
sws = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt,
|
||||
pos.w, pos.h, screenFormat,
|
||||
sws = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt,
|
||||
pos.w, pos.h, screenFormat,
|
||||
SWS_BICUBIC, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
@ -357,7 +364,7 @@ void CVideoPlayer::close()
|
||||
|
||||
if (frame)
|
||||
{
|
||||
av_frame_free(&frame);//will be set to null
|
||||
av_frame_free(&frame);//will be set to null
|
||||
}
|
||||
|
||||
if (codec)
|
||||
|
@ -133,13 +133,13 @@ bool CAttackAnimation::checkInitialConditions()
|
||||
}
|
||||
|
||||
CAttackAnimation::CAttackAnimation(CBattleInterface *_owner, const CStack *attacker, BattleHex _dest, const CStack *defender)
|
||||
: CBattleStackAnimation(_owner, attacker),
|
||||
soundPlayed(false),
|
||||
dest(_dest), attackedStack(defender), attackingStack(attacker)
|
||||
: CBattleStackAnimation(_owner, attacker),
|
||||
shooting(false), group(CCreatureAnim::SHOOT_FRONT),
|
||||
soundPlayed(false),
|
||||
dest(_dest), attackedStack(defender), attackingStack(attacker)
|
||||
{
|
||||
|
||||
assert(attackingStack && "attackingStack is nullptr in CBattleAttack::CBattleAttack !\n");
|
||||
bool isCatapultAttack = attackingStack->hasBonusOfType(Bonus::CATAPULT)
|
||||
bool isCatapultAttack = attackingStack->hasBonusOfType(Bonus::CATAPULT)
|
||||
&& owner->getCurrentPlayerInterface()->cb->battleHexToWallPart(_dest) >= 0;
|
||||
|
||||
assert(attackedStack || isCatapultAttack);
|
||||
@ -150,7 +150,7 @@ CAttackAnimation::CAttackAnimation(CBattleInterface *_owner, const CStack *attac
|
||||
CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, CBattleInterface * _owner)
|
||||
: CBattleStackAnimation(_owner, _attackedInfo.defender),
|
||||
attacker(_attackedInfo.attacker), rangedAttack(_attackedInfo.indirectAttack),
|
||||
killed(_attackedInfo.killed)
|
||||
killed(_attackedInfo.killed), timeToWait(0)
|
||||
{
|
||||
logAnim->debugStream() << "Created defence anim for " << _attackedInfo.defender->getName();
|
||||
}
|
||||
@ -198,7 +198,7 @@ bool CDefenceAnimation::init()
|
||||
//unit reversed
|
||||
|
||||
if(rangedAttack) //delay hit animation
|
||||
{
|
||||
{
|
||||
for(std::list<ProjectileInfo>::const_iterator it = owner->projectiles.begin(); it != owner->projectiles.end(); ++it)
|
||||
{
|
||||
if(it->creID == attacker->getCreature()->idNumber)
|
||||
@ -243,7 +243,7 @@ CCreatureAnim::EAnimType CDefenceAnimation::getMyAnimType()
|
||||
{
|
||||
if(killed)
|
||||
return CCreatureAnim::DEATH;
|
||||
|
||||
|
||||
if (vstd::contains(stack->state, EBattleStackState::DEFENDING_ANIM))
|
||||
return CCreatureAnim::DEFENCE;
|
||||
|
||||
@ -281,7 +281,7 @@ void CDefenceAnimation::endAnim()
|
||||
delete this;
|
||||
}
|
||||
|
||||
CDummyAnimation::CDummyAnimation(CBattleInterface * _owner, int howManyFrames)
|
||||
CDummyAnimation::CDummyAnimation(CBattleInterface * _owner, int howManyFrames)
|
||||
: CBattleAnimation(_owner), counter(0), howMany(howManyFrames)
|
||||
{
|
||||
logAnim->debugStream() << "Created dummy animation for " << howManyFrames <<" frames";
|
||||
@ -314,7 +314,7 @@ bool CMeleeAttackAnimation::init()
|
||||
if(!attackingStack || myAnim->isDead())
|
||||
{
|
||||
endAnim();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ bool CMeleeAttackAnimation::init()
|
||||
}
|
||||
|
||||
CMeleeAttackAnimation::CMeleeAttackAnimation(CBattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked)
|
||||
: CAttackAnimation(_owner, attacker, _dest, _attacked)
|
||||
: CAttackAnimation(_owner, attacker, _dest, _attacked)
|
||||
{
|
||||
logAnim->debugStream() << "Created melee attack anim for " << attacker->getName();
|
||||
}
|
||||
@ -534,7 +534,7 @@ CMovementAnimation::CMovementAnimation(CBattleInterface *_owner, const CStack *_
|
||||
}
|
||||
|
||||
CMovementEndAnimation::CMovementEndAnimation(CBattleInterface * _owner, const CStack * _stack, BattleHex destTile)
|
||||
: CBattleStackAnimation(_owner, _stack), destinationTile(destTile)
|
||||
: CBattleStackAnimation(_owner, _stack), destinationTile(destTile)
|
||||
{
|
||||
logAnim->debugStream() << "Created movement end anim for " << stack->getName();
|
||||
}
|
||||
@ -573,7 +573,7 @@ void CMovementEndAnimation::endAnim()
|
||||
}
|
||||
|
||||
CMovementStartAnimation::CMovementStartAnimation(CBattleInterface * _owner, const CStack * _stack)
|
||||
: CBattleStackAnimation(_owner, _stack)
|
||||
: CBattleStackAnimation(_owner, _stack)
|
||||
{
|
||||
logAnim->debugStream() << "Created movement start anim for " << stack->getName();
|
||||
}
|
||||
@ -776,7 +776,7 @@ bool CShootingAnimation::init()
|
||||
spi.dx = (destPos.x - spi.x) / spi.lastStep;
|
||||
spi.dy = (destPos.y - spi.y) / spi.lastStep;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Catapult attack
|
||||
spi.catapultInfo.reset(new CatapultProjectileInfo(Point(spi.x, spi.y), destPos));
|
||||
@ -885,7 +885,7 @@ CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, std::str
|
||||
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, std::string _customAnim, BattleHex _destTile, bool _Vflip, bool _alignToBottom)
|
||||
:CBattleAnimation(_owner), effect(-1), destTile(_destTile), customAnim(_customAnim), x(-1), y(-1), dx(0), dy(0), Vflip(_Vflip), alignToBottom(_alignToBottom)
|
||||
{
|
||||
logAnim->debugStream() << "Created spell anim for " << customAnim;
|
||||
logAnim->debugStream() << "Created spell anim for " << customAnim;
|
||||
}
|
||||
|
||||
|
||||
@ -893,21 +893,21 @@ bool CSpellEffectAnimation::init()
|
||||
{
|
||||
if(!isEarliest(true))
|
||||
return false;
|
||||
|
||||
|
||||
if(customAnim.empty() && effect != ui32(-1) && !graphics->battleACToDef[effect].empty())
|
||||
{
|
||||
{
|
||||
customAnim = graphics->battleACToDef[effect][0];
|
||||
}
|
||||
|
||||
|
||||
if(customAnim.empty())
|
||||
{
|
||||
endAnim();
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const bool areaEffect = (!destTile.isValid() && x == -1 && y == -1);
|
||||
|
||||
if(areaEffect) //f.e. armageddon
|
||||
if(areaEffect) //f.e. armageddon
|
||||
{
|
||||
CDefHandler * anim = CDefHandler::giveDef(customAnim);
|
||||
|
||||
@ -934,7 +934,7 @@ bool CSpellEffectAnimation::init()
|
||||
owner->battleEffects.push_back(be);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete anim;
|
||||
}
|
||||
else // Effects targeted at a specific creature/hex.
|
||||
@ -956,9 +956,9 @@ bool CSpellEffectAnimation::init()
|
||||
|
||||
be.currentFrame = 0;
|
||||
be.maxFrame = be.anim->ourImages.size();
|
||||
|
||||
|
||||
//todo: lightning anim frame count override
|
||||
|
||||
|
||||
// if(effect == 1)
|
||||
// be.maxFrame = 3;
|
||||
|
||||
@ -970,7 +970,7 @@ bool CSpellEffectAnimation::init()
|
||||
{
|
||||
be.x = x;
|
||||
}
|
||||
|
||||
|
||||
if(y == -1)
|
||||
{
|
||||
if(alignToBottom)
|
||||
@ -993,7 +993,7 @@ bool CSpellEffectAnimation::init()
|
||||
owner->battleEffects.push_back(be);
|
||||
|
||||
}
|
||||
//battleEffects
|
||||
//battleEffects
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
CondSh<bool> CBattleInterface::animsAreDisplayed;
|
||||
CondSh<bool> CBattleInterface::animsAreDisplayed(false);
|
||||
|
||||
static void onAnimationFinished(const CStack *stack, CCreatureAnimation *anim)
|
||||
{
|
||||
|
@ -191,7 +191,7 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
|
||||
if(myOwner->spellDestSelectMode) //we are casting a spell
|
||||
return;
|
||||
|
||||
if(!down && myHero != nullptr && myOwner->myTurn && myOwner->getCurrentPlayerInterface()->cb->battleCanCastSpell()) //check conditions
|
||||
if(myHero != nullptr && !down && myOwner->myTurn && myOwner->getCurrentPlayerInterface()->cb->battleCanCastSpell()) //check conditions
|
||||
{
|
||||
for(int it=0; it<GameConstants::BFIELD_SIZE; ++it) //do nothing when any hex is hovered - hero's animation overlaps battlefield
|
||||
{
|
||||
|
@ -1557,8 +1557,7 @@ bool CFadeAnimation::isFinished() const
|
||||
}
|
||||
|
||||
CFadeAnimation::CFadeAnimation()
|
||||
: fadingSurface(nullptr),
|
||||
fading(false),
|
||||
: delta(0), fadingSurface(nullptr), fading(false), fadingCounter(0), shouldFreeSurface(false),
|
||||
fadingMode(EMode::NONE)
|
||||
{
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
extern std::queue<SDL_Event> events;
|
||||
extern boost::mutex eventsM;
|
||||
|
||||
CondSh<bool> CGuiHandler::terminate_cond;
|
||||
CondSh<bool> CGuiHandler::terminate_cond(false);
|
||||
boost::thread_specific_ptr<bool> inGuiThread;
|
||||
|
||||
SObjectConstruction::SObjectConstruction(CIntObject *obj)
|
||||
@ -170,15 +170,15 @@ void CGuiHandler::updateTime()
|
||||
|
||||
void CGuiHandler::handleEvents()
|
||||
{
|
||||
//player interface may want special event handling
|
||||
//player interface may want special event handling
|
||||
if(nullptr != LOCPLINT && LOCPLINT->capturedAllEvents())
|
||||
return;
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(eventsM);
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(eventsM);
|
||||
while(!events.empty())
|
||||
{
|
||||
SDL_Event ev = events.front();
|
||||
events.pop();
|
||||
events.pop();
|
||||
this->handleEvent(&ev);
|
||||
}
|
||||
}
|
||||
@ -286,14 +286,14 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
|
||||
{
|
||||
it->textInputed(sEvent->text);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sEvent->type == SDL_TEXTEDITING)
|
||||
{
|
||||
for(auto it : textInterested)
|
||||
{
|
||||
it->textEdited(sEvent->edit);
|
||||
}
|
||||
}
|
||||
}
|
||||
//todo: muiltitouch
|
||||
else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_LEFT))
|
||||
{
|
||||
@ -398,9 +398,9 @@ void CGuiHandler::renderFrame()
|
||||
// Updating GUI requires locking pim mutex (that protects screen and GUI state).
|
||||
// During game:
|
||||
// When ending the game, the pim mutex might be hold by other thread,
|
||||
// that will notify us about the ending game by setting terminate_cond flag.
|
||||
//in PreGame terminate_cond stay false
|
||||
|
||||
// that will notify us about the ending game by setting terminate_cond flag.
|
||||
//in PreGame terminate_cond stay false
|
||||
|
||||
bool acquiredTheLockOnPim = false; //for tracking whether pim mutex locking succeeded
|
||||
while(!terminate_cond.get() && !(acquiredTheLockOnPim = CPlayerInterface::pim->try_lock())) //try acquiring long until it succeeds or we are told to terminate
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(15));
|
||||
@ -412,25 +412,25 @@ void CGuiHandler::renderFrame()
|
||||
|
||||
if(nullptr != curInt)
|
||||
curInt->update();
|
||||
|
||||
|
||||
if (settings["general"]["showfps"].Bool())
|
||||
drawFPSCounter();
|
||||
|
||||
drawFPSCounter();
|
||||
|
||||
// draw the mouse cursor and update the screen
|
||||
CCS->curh->render();
|
||||
|
||||
if(0 != SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr))
|
||||
logGlobal->errorStream() << __FUNCTION__ << " SDL_RenderCopy " << SDL_GetError();
|
||||
|
||||
SDL_RenderPresent(mainRenderer);
|
||||
}
|
||||
SDL_RenderPresent(mainRenderer);
|
||||
}
|
||||
|
||||
mainFPSmng->framerateDelay(); // holds a constant FPS
|
||||
mainFPSmng->framerateDelay(); // holds a constant FPS
|
||||
}
|
||||
|
||||
|
||||
CGuiHandler::CGuiHandler()
|
||||
:lastClick(-500, -500)
|
||||
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false)
|
||||
{
|
||||
curInt = nullptr;
|
||||
current = nullptr;
|
||||
@ -439,7 +439,7 @@ CGuiHandler::CGuiHandler()
|
||||
// Creates the FPS manager and sets the framerate to 48 which is doubled the value of the original Heroes 3 FPS rate
|
||||
mainFPSmng = new CFramerateManager(48);
|
||||
//do not init CFramerateManager here --AVS
|
||||
|
||||
|
||||
terminate_cond.set(false);
|
||||
}
|
||||
|
||||
@ -477,7 +477,7 @@ SDL_Keycode CGuiHandler::arrowToNum(SDL_Keycode key)
|
||||
return SDLK_KP_6;
|
||||
default:
|
||||
throw std::runtime_error("Wrong key!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Keycode CGuiHandler::numToDigit(SDL_Keycode key)
|
||||
@ -495,7 +495,7 @@ SDL_Keycode CGuiHandler::numToDigit(SDL_Keycode key)
|
||||
REMOVE_KP(6)
|
||||
REMOVE_KP(7)
|
||||
REMOVE_KP(8)
|
||||
REMOVE_KP(9)
|
||||
REMOVE_KP(9)
|
||||
REMOVE_KP(PERIOD)
|
||||
REMOVE_KP(MINUS)
|
||||
REMOVE_KP(PLUS)
|
||||
@ -546,6 +546,8 @@ CFramerateManager::CFramerateManager(int rate)
|
||||
this->fps = 0;
|
||||
this->accumulatedFrames = 0;
|
||||
this->accumulatedTime = 0;
|
||||
this->lastticks = 0;
|
||||
this->timeElapsed = 0;
|
||||
}
|
||||
|
||||
void CFramerateManager::init()
|
||||
@ -557,23 +559,23 @@ void CFramerateManager::framerateDelay()
|
||||
{
|
||||
ui32 currentTicks = SDL_GetTicks();
|
||||
timeElapsed = currentTicks - lastticks;
|
||||
|
||||
|
||||
// FPS is higher than it should be, then wait some time
|
||||
if (timeElapsed < rateticks)
|
||||
{
|
||||
SDL_Delay(ceil(this->rateticks) - timeElapsed);
|
||||
}
|
||||
|
||||
|
||||
accumulatedTime += timeElapsed;
|
||||
accumulatedFrames++;
|
||||
|
||||
if(accumulatedFrames >= 100)
|
||||
{
|
||||
//about 2 second should be passed
|
||||
fps = ceil(1000.0 / (accumulatedTime/accumulatedFrames));
|
||||
fps = ceil(1000.0 / (accumulatedTime/accumulatedFrames));
|
||||
accumulatedTime = 0;
|
||||
accumulatedFrames = 0;
|
||||
};
|
||||
accumulatedFrames = 0;
|
||||
};
|
||||
|
||||
currentTicks = SDL_GetTicks();
|
||||
// recalculate timeElapsed for external calls via getElapsed()
|
||||
|
@ -49,11 +49,11 @@ public:
|
||||
|
||||
private:
|
||||
typedef std::list<CIntObject*> CIntObjectList;
|
||||
|
||||
|
||||
//active GUI elements (listening for events
|
||||
CIntObjectList lclickable,
|
||||
rclickable,
|
||||
hoverable,
|
||||
CIntObjectList lclickable,
|
||||
rclickable,
|
||||
hoverable,
|
||||
keyinterested,
|
||||
motioninterested,
|
||||
timeinterested,
|
||||
@ -61,12 +61,12 @@ private:
|
||||
doubleClickInterested,
|
||||
textInterested;
|
||||
|
||||
|
||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
||||
|
||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
||||
public:
|
||||
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
||||
void handleElementDeActivate(CIntObject * elem, ui16 activityFlag);
|
||||
|
||||
|
||||
public:
|
||||
//objs to blit
|
||||
std::vector<IShowable*> objsToBlit;
|
||||
@ -77,9 +77,13 @@ public:
|
||||
Point lastClick;
|
||||
unsigned lastClickTime;
|
||||
|
||||
ui8 defActionsDef; //default auto actions
|
||||
bool captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
|
||||
std::list<CIntObject *> createdObj; //stack of objs being created
|
||||
|
||||
CGuiHandler();
|
||||
~CGuiHandler();
|
||||
|
||||
|
||||
void renderFrame();
|
||||
|
||||
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
|
||||
@ -99,9 +103,6 @@ public:
|
||||
void fakeMouseMove();
|
||||
void breakEventHandling(); //current event won't be propagated anymore
|
||||
void drawFPSCounter(); // draws the FPS to the upper left corner of the screen
|
||||
ui8 defActionsDef; //default auto actions
|
||||
ui8 captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
|
||||
std::list<CIntObject *> createdObj; //stack of objs being created
|
||||
|
||||
static SDL_Keycode arrowToNum(SDL_Keycode key); //converts arrow key to according numpad key
|
||||
static SDL_Keycode numToDigit(SDL_Keycode key);//converts numpad digit key to normal digit key
|
||||
@ -109,7 +110,7 @@ public:
|
||||
static bool isArrowKey(SDL_Keycode key);
|
||||
static bool amIGuiThread();
|
||||
static void pushSDLEvent(int type, int usercode = 0);
|
||||
|
||||
|
||||
static CondSh<bool> terminate_cond; // confirm termination
|
||||
};
|
||||
|
||||
|
@ -709,6 +709,14 @@ CMapHandler::CMapPuzzleViewBlitter::CMapPuzzleViewBlitter(CMapHandler * parent)
|
||||
unblittableObjects.push_back(Obj::HOLE);
|
||||
}
|
||||
|
||||
CMapHandler::CMapBlitter::CMapBlitter(CMapHandler * p)
|
||||
:parent(p), tileSize(0), halfTileSizeCeil(0), info(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CMapHandler::CMapBlitter::~CMapBlitter() = default;
|
||||
|
||||
void CMapHandler::CMapBlitter::drawFrame(SDL_Surface * targetSurf) const
|
||||
{
|
||||
Rect destRect(realTileRect);
|
||||
@ -1369,6 +1377,9 @@ CMapHandler::CMapHandler()
|
||||
worldViewBlitter = new CMapWorldViewBlitter(this);
|
||||
puzzleViewBlitter = new CMapPuzzleViewBlitter(this);
|
||||
fadeAnimCounter = 0;
|
||||
map = nullptr;
|
||||
tilesW = tilesH = 0;
|
||||
offsetX = offsetY = 0;
|
||||
|
||||
egdeAnimation = make_unique<CAnimation>("EDG");
|
||||
egdeAnimation->preload();
|
||||
@ -1405,6 +1416,11 @@ void CMapHandler::discardWorldViewCache()
|
||||
cache.discardWorldViewCache();
|
||||
}
|
||||
|
||||
CMapHandler::CMapCache::CMapCache()
|
||||
{
|
||||
worldViewCachedScale = 0;
|
||||
}
|
||||
|
||||
void CMapHandler::CMapCache::discardWorldViewCache()
|
||||
{
|
||||
for(auto & cache : data)
|
||||
|
@ -162,6 +162,7 @@ class CMapHandler
|
||||
std::array< std::map<intptr_t, std::unique_ptr<IImage>>, (ui8)EMapCacheType::AFTER_LAST> data;
|
||||
float worldViewCachedScale;
|
||||
public:
|
||||
CMapCache();
|
||||
/// destroys all cached data (frees surfaces)
|
||||
void discardWorldViewCache();
|
||||
/// updates scale and determines if currently cached data is still valid
|
||||
@ -254,8 +255,8 @@ class CMapHandler
|
||||
IImage * findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const;
|
||||
|
||||
public:
|
||||
CMapBlitter(CMapHandler * p) : parent(p) {}
|
||||
virtual ~CMapBlitter(){}
|
||||
CMapBlitter(CMapHandler * p);
|
||||
virtual ~CMapBlitter();
|
||||
void blit(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
||||
/// helper method that chooses correct bitmap(s) for given object
|
||||
AnimBitmapHolder findObjectBitmap(const CGObjectInstance * obj, int anim) const;
|
||||
|
@ -785,7 +785,12 @@ void CInfoBar::CVisibleInfo::loadGameStatus()
|
||||
//get amount of halls of each level
|
||||
std::vector<int> halls(4, 0);
|
||||
for(auto town : LOCPLINT->towns)
|
||||
halls[town->hallLevel()]++;
|
||||
{
|
||||
int hallLevel = town->hallLevel();
|
||||
//negative value means no village hall, unlikely but possible
|
||||
if(hallLevel >= 0)
|
||||
halls.at(hallLevel)++;
|
||||
}
|
||||
|
||||
std::vector<PlayerColor> allies, enemies;
|
||||
|
||||
|
@ -24,39 +24,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
ClickableArea::ClickableArea(CIntObject * object, CFunctionList<void()> callback):
|
||||
callback(callback),
|
||||
area(nullptr)
|
||||
{
|
||||
if (object)
|
||||
pos = object->pos;
|
||||
setArea(object);
|
||||
}
|
||||
|
||||
void ClickableArea::addCallback(std::function<void()> callback)
|
||||
{
|
||||
this->callback += callback;
|
||||
}
|
||||
|
||||
void ClickableArea::setArea(CIntObject * object)
|
||||
{
|
||||
delete area;
|
||||
area = object;
|
||||
addChild(area);
|
||||
pos.w = object->pos.w;
|
||||
pos.h = object->pos.h;
|
||||
}
|
||||
|
||||
void ClickableArea::onClick()
|
||||
{
|
||||
callback();
|
||||
}
|
||||
|
||||
void ClickableArea::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if (down)
|
||||
onClick();
|
||||
}
|
||||
|
||||
void CButton::update()
|
||||
{
|
||||
|
@ -26,24 +26,6 @@ namespace config
|
||||
*
|
||||
*/
|
||||
|
||||
class ClickableArea : public CIntObject //TODO: derive from LRCLickableArea? Or somehow use its right-click/hover data?
|
||||
{
|
||||
CFunctionList<void()> callback;
|
||||
|
||||
CIntObject * area;
|
||||
|
||||
protected:
|
||||
void onClick();
|
||||
|
||||
public:
|
||||
ClickableArea(CIntObject * object, CFunctionList<void()> callback);
|
||||
|
||||
void addCallback(std::function<void()> callback);
|
||||
void setArea(CIntObject * object);
|
||||
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
};
|
||||
|
||||
/// Typical Heroes 3 button which can be inactive or active and can
|
||||
/// hold further information if you right-click it
|
||||
class CButton : public CKeyShortcut
|
||||
@ -151,13 +133,6 @@ public:
|
||||
void addCallback(std::function<void(bool)> callback);
|
||||
};
|
||||
|
||||
class ClickableToggle : public ClickableArea, public CToggleBase
|
||||
{
|
||||
public:
|
||||
ClickableToggle(CIntObject * object, CFunctionList<void()> selectFun, CFunctionList<void()> deselectFun);
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
};
|
||||
|
||||
/// A button which can be selected/deselected, checkbox
|
||||
class CToggleButton : public CButton, public CToggleBase
|
||||
{
|
||||
@ -224,9 +199,6 @@ class CSlider : public CIntObject
|
||||
int capacity;//how many elements can be active at same time (e.g. hero list = 5)
|
||||
int positions; //number of highest position (0 if there is only one)
|
||||
bool horizontal;
|
||||
bool wheelScrolling;
|
||||
bool keyScrolling;
|
||||
|
||||
int amount; //total amount of elements (e.g. hero list = 0-8)
|
||||
int value; //first active element
|
||||
int scrollStep; // how many elements will be scrolled via one click, default = 1
|
||||
|
@ -239,7 +239,7 @@ bool CHeroArtPlace::askToAssemble(const CArtifactInstance *art, ArtifactPosition
|
||||
|
||||
void CHeroArtPlace::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && ourArt && !locked && text.size() && !picked) //if there is no description or it's a lock, do nothing ;]
|
||||
if(ourArt && down && ourArt && !locked && text.size() && !picked) //if there is no description or it's a lock, do nothing ;]
|
||||
{
|
||||
if (slotID < GameConstants::BACKPACK_START)
|
||||
{
|
||||
@ -946,6 +946,7 @@ bool CArtifactsOfHero::SCommonPart::Artpos::valid()
|
||||
|
||||
CArtPlace::CArtPlace(Point position, const CArtifactInstance * Art) : ourArt(Art)
|
||||
{
|
||||
image = nullptr;
|
||||
pos += position;
|
||||
pos.w = pos.h = 44;
|
||||
}
|
||||
@ -968,13 +969,13 @@ CCommanderArtPlace::CCommanderArtPlace(Point position, const CGHeroInstance * co
|
||||
|
||||
void CCommanderArtPlace::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if (down && ourArt && text.size())
|
||||
if (ourArt && text.size() && down)
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->localizedTexts["commanderWindow"]["artifactMessage"].String(), [this] { returnArtToHeroCallback(); }, [] {});
|
||||
}
|
||||
|
||||
void CCommanderArtPlace::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if (down && ourArt && text.size())
|
||||
if (ourArt && text.size() && down)
|
||||
CArtPlace::clickRight(down, previousState);
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ bool CGarrisonSlot::mustForceReselection() const
|
||||
|
||||
void CGarrisonSlot::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && creature)
|
||||
if(creature && down)
|
||||
{
|
||||
GH.pushInt(new CStackWindow(myStack, true));
|
||||
}
|
||||
@ -475,6 +475,7 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point &garsOffset,
|
||||
inSplittingMode(false),
|
||||
interx(inx),
|
||||
garOffset(garsOffset),
|
||||
pb(false),
|
||||
smallIcons(smallImgs),
|
||||
removableUnits(_removableUnits),
|
||||
twoRows(_twoRows)
|
||||
@ -547,17 +548,23 @@ CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance
|
||||
quit = new CButton(Point(399, 314), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&]{ close(); }, SDLK_RETURN);
|
||||
|
||||
std::string titleText;
|
||||
if (garr->armedObjs[1]->tempOwner == garr->armedObjs[0]->tempOwner)
|
||||
if (down->tempOwner == up->tempOwner)
|
||||
titleText = CGI->generaltexth->allTexts[709];
|
||||
else
|
||||
{
|
||||
titleText = CGI->generaltexth->allTexts[35];
|
||||
boost::algorithm::replace_first(titleText, "%s", garr->armedObjs[0]->Slots().begin()->second->type->namePl);
|
||||
//assume that this is joining monsters dialog
|
||||
if(up->Slots().size() > 0)
|
||||
{
|
||||
titleText = CGI->generaltexth->allTexts[35];
|
||||
boost::algorithm::replace_first(titleText, "%s", up->Slots().begin()->second->type->namePl);
|
||||
}
|
||||
else
|
||||
logGlobal->error("Invalid armed instance for garrison window.");
|
||||
}
|
||||
new CLabel(275, 30, FONT_BIG, CENTER, Colors::YELLOW, titleText);
|
||||
|
||||
new CAnimImage("CREST58", garr->armedObjs[0]->getOwner().getNum(), 0, 28, 124);
|
||||
new CAnimImage("PortraitsLarge", dynamic_cast<const CGHeroInstance*>(garr->armedObjs[1])->portrait, 0, 29, 222);
|
||||
new CAnimImage("CREST58", up->getOwner().getNum(), 0, 28, 124);
|
||||
new CAnimImage("PortraitsLarge", down->portrait, 0, 29, 222);
|
||||
}
|
||||
|
||||
CGarrisonHolder::CGarrisonHolder()
|
||||
|
@ -78,19 +78,14 @@ public:
|
||||
std::vector<CButton *> splitButtons; ///< May be empty if no buttons
|
||||
|
||||
SlotID p2; ///< TODO: comment me
|
||||
int shiftPos; ///< 1st slot of the second row, set shiftPoint for effect
|
||||
bool pb,
|
||||
smallIcons, ///< true - 32x32 imgs, false - 58x64
|
||||
removableUnits, ///< player Can remove units from up
|
||||
twoRows, ///< slots Will be placed in 2 rows
|
||||
owned[2]; ///< player Owns up or down army ([0] upper, [1] lower)
|
||||
|
||||
// const CCreatureSet *set1; ///< Top set of creatures
|
||||
// const CCreatureSet *set2; ///< Bottom set of creatures
|
||||
|
||||
std::vector<CGarrisonSlot*> slotsUp, slotsDown; ///< Slots of upper and lower garrison
|
||||
const CArmedInstance *armedObjs[2]; ///< [0] is upper, [1] is down
|
||||
//const CArmedInstance *oup, *odown; ///< Upper and lower garrisons (heroes or towns)
|
||||
|
||||
void setArmy(const CArmedInstance *army, bool bottomGarrison);
|
||||
void addSplitBtn(CButton * button);
|
||||
|
@ -94,7 +94,7 @@ void LRClickableAreaWTextComp::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
|
||||
LRClickableAreaWTextComp::LRClickableAreaWTextComp(const Rect &Pos, int BaseType)
|
||||
: LRClickableAreaWText(Pos), baseType(BaseType), bonusValue(-1)
|
||||
: LRClickableAreaWText(Pos), baseType(BaseType), bonusValue(-1), type(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -134,13 +134,13 @@ CHeroArea::CHeroArea(int x, int y, const CGHeroInstance * _hero):hero(_hero)
|
||||
|
||||
void CHeroArea::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if((!down) && previousState && hero)
|
||||
if(hero && (!down) && previousState)
|
||||
LOCPLINT->openHeroWindow(hero);
|
||||
}
|
||||
|
||||
void CHeroArea::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if((!down) && previousState && hero)
|
||||
if(hero && (!down) && previousState)
|
||||
LOCPLINT->openHeroWindow(hero);
|
||||
}
|
||||
|
||||
@ -154,24 +154,24 @@ void CHeroArea::hover(bool on)
|
||||
|
||||
void LRClickableAreaOpenTown::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if((!down) && previousState && town)
|
||||
{
|
||||
if(town && (!down) && previousState)
|
||||
{
|
||||
LOCPLINT->openTownWindow(town);
|
||||
if ( type == 2 )
|
||||
LOCPLINT->castleInt->builds->buildingClicked(BuildingID::VILLAGE_HALL);
|
||||
else if ( type == 3 && town->fortLevel() )
|
||||
LOCPLINT->castleInt->builds->buildingClicked(BuildingID::FORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LRClickableAreaOpenTown::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if((!down) && previousState && town)
|
||||
if(town && (!down) && previousState)
|
||||
LOCPLINT->openTownWindow(town);//TODO: popup?
|
||||
}
|
||||
|
||||
LRClickableAreaOpenTown::LRClickableAreaOpenTown()
|
||||
: LRClickableAreaWTextComp(Rect(0,0,0,0), -1)
|
||||
LRClickableAreaOpenTown::LRClickableAreaOpenTown(const Rect & Pos, const CGTownInstance * Town)
|
||||
: LRClickableAreaWTextComp(Pos, -1), town(Town)
|
||||
{
|
||||
}
|
||||
|
||||
@ -376,9 +376,9 @@ void MoraleLuckBox::set(const IBonusBearer *node)
|
||||
baseType = componentType[morale];
|
||||
text = CGI->generaltexth->arraytxt[textId[morale]];
|
||||
boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
|
||||
|
||||
if (morale && node && (node->hasBonusOfType(Bonus::UNDEAD)
|
||||
|| node->hasBonusOfType(Bonus::BLOCK_MORALE)
|
||||
|
||||
if (morale && node && (node->hasBonusOfType(Bonus::UNDEAD)
|
||||
|| node->hasBonusOfType(Bonus::BLOCK_MORALE)
|
||||
|| node->hasBonusOfType(Bonus::NON_LIVING)))
|
||||
{
|
||||
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
||||
|
@ -139,7 +139,7 @@ public:
|
||||
const CGTownInstance * town;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
LRClickableAreaOpenTown();
|
||||
LRClickableAreaOpenTown(const Rect & Pos, const CGTownInstance * Town);
|
||||
};
|
||||
|
||||
class MoraleLuckBox : public LRClickableAreaWTextComp
|
||||
|
@ -577,6 +577,7 @@ void CTextInput::numberFilter(std::string & text, const std::string & oldText, i
|
||||
|
||||
CFocusable::CFocusable()
|
||||
{
|
||||
focus = false;
|
||||
focusables.push_back(this);
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@ static void setScrollingCursor(ui8 direction)
|
||||
|
||||
CTerrainRect::CTerrainRect()
|
||||
: fadeSurface(nullptr),
|
||||
lastRedrawStatus(EMapAnimRedrawStatus::OK),
|
||||
fadeAnim(new CFadeAnimation()),
|
||||
curHoveredTile(-1,-1,-1),
|
||||
currentPath(nullptr)
|
||||
|
@ -43,7 +43,7 @@ enum class EAdvMapMode
|
||||
class CAdventureOptions : public CWindowObject
|
||||
{
|
||||
public:
|
||||
CButton *exit, *viewWorld, *puzzle, *dig, *scenInfo, *replay;
|
||||
CButton *exit, *viewWorld, *puzzle, *dig, *scenInfo/*, *replay*/;
|
||||
|
||||
CAdventureOptions();
|
||||
static void showScenarioInfo();
|
||||
|
@ -109,7 +109,7 @@ void CBuildingRect::hover(bool on)
|
||||
|
||||
void CBuildingRect::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if( previousState && !down && area && (parent->selectedBuilding==this) && getBuilding() )
|
||||
if( previousState && getBuilding() && area && !down && (parent->selectedBuilding==this))
|
||||
if (!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
|
||||
parent->buildingClicked(getBuilding()->bid);
|
||||
}
|
||||
@ -398,7 +398,7 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
|
||||
|
||||
void CHeroGSlot::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && hero)
|
||||
if(hero && down)
|
||||
{
|
||||
GH.pushInt(new CInfoBoxPopup(Point(pos.x + 175, pos.y + 100), hero));
|
||||
}
|
||||
@ -1014,6 +1014,7 @@ CCreaInfo::CCreaInfo(Point position, const CGTownInstance *Town, int Level, bool
|
||||
level = -1;
|
||||
label = nullptr;
|
||||
picture = nullptr;
|
||||
creature = nullptr;
|
||||
return;//No creature
|
||||
}
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
@ -1125,6 +1126,8 @@ CTownInfo::CTownInfo(int posX, int posY, const CGTownInstance* Town, bool townHa
|
||||
pos.y += posY;
|
||||
int buildID;
|
||||
|
||||
picture = nullptr;
|
||||
|
||||
if (townHall)
|
||||
{
|
||||
buildID = 10 + town->hallLevel();
|
||||
@ -1134,7 +1137,7 @@ CTownInfo::CTownInfo(int posX, int posY, const CGTownInstance* Town, bool townHa
|
||||
{
|
||||
buildID = 6 + town->fortLevel();
|
||||
if (buildID == 6)
|
||||
return;
|
||||
return;//FIXME: suspicious statement, fix or comment
|
||||
picture = new CAnimImage("ITMCL.DEF", town->fortLevel()-1);
|
||||
}
|
||||
building = town->town->buildings.at(BuildingID(buildID));
|
||||
@ -1154,7 +1157,7 @@ void CTownInfo::hover(bool on)
|
||||
|
||||
void CTownInfo::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && building)
|
||||
if(building && down)
|
||||
CRClickPopup::createAndPush(CInfoWindow::genText(building->Name(), building->Description()),
|
||||
new CComponent(CComponent::building, building->town->faction->index, building->bid));
|
||||
|
||||
@ -1302,11 +1305,11 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance *
|
||||
static int panelIndex[12] = { 3, 3, 3, 0, 0, 2, 2, 1, 2, 2, 3, 3};
|
||||
static int iconIndex[12] = {-1, -1, -1, 0, 0, 1, 2, -1, 1, 1, -1, -1};
|
||||
|
||||
picture = new CAnimImage(town->town->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
|
||||
panel = new CAnimImage("TPTHBAR", panelIndex[state], 0, 1, 73);
|
||||
if ( iconIndex[state] >=0 )
|
||||
icon = new CAnimImage("TPTHCHK", iconIndex[state], 0, 136, 56);
|
||||
label = new CLabel(75, 81, FONT_SMALL, CENTER, Colors::WHITE, building->Name());
|
||||
new CAnimImage(town->town->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
|
||||
new CAnimImage("TPTHBAR", panelIndex[state], 0, 1, 73);
|
||||
if (iconIndex[state] >=0)
|
||||
new CAnimImage("TPTHCHK", iconIndex[state], 0, 136, 56);
|
||||
new CLabel(75, 81, FONT_SMALL, CENTER, Colors::WHITE, building->Name());
|
||||
|
||||
//todo: add support for all possible states
|
||||
if(state >= EBuildingState::BUILDING_ERROR)
|
||||
@ -1427,12 +1430,12 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
|
||||
std::string tooltipYes = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->Name());
|
||||
std::string tooltipNo = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % building->Name());
|
||||
|
||||
buy = new CButton(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&]{ buyFunc(); }, SDLK_RETURN);
|
||||
CButton * buy = new CButton(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&]{ buyFunc(); }, SDLK_RETURN);
|
||||
buy->borderColor = Colors::METALLIC_GOLD;
|
||||
|
||||
cancel = new CButton(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo), [&] { close();}, SDLK_ESCAPE);
|
||||
cancel->borderColor = Colors::METALLIC_GOLD;
|
||||
buy->block(state!=7 || LOCPLINT->playerID != town->tempOwner);
|
||||
|
||||
CButton * cancel = new CButton(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo), [&] { close();}, SDLK_ESCAPE);
|
||||
cancel->borderColor = Colors::METALLIC_GOLD;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1597,10 +1600,11 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);//Activate only if dwelling is present
|
||||
|
||||
icons = new CPicture("TPCAINFO", 261, 3);
|
||||
|
||||
if (getMyBuilding() != nullptr)
|
||||
{
|
||||
buildingPic = new CAnimImage(town->town->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21);
|
||||
dwellingName = new CLabel(78, 101, FONT_SMALL, CENTER, Colors::WHITE, getMyBuilding()->Name());
|
||||
new CAnimImage(town->town->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21);
|
||||
new CLabel(78, 101, FONT_SMALL, CENTER, Colors::WHITE, getMyBuilding()->Name());
|
||||
|
||||
if (vstd::contains(town->builtBuildings, getMyBuilding()->bid))
|
||||
{
|
||||
@ -1613,8 +1617,8 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
|
||||
if (getMyCreature() != nullptr)
|
||||
{
|
||||
hoverText = boost::str(boost::format(CGI->generaltexth->tcommands[21]) % getMyCreature()->namePl);
|
||||
creatureAnim = new CCreaturePic(159, 4, getMyCreature(), false);
|
||||
creatureName = new CLabel(78, 11, FONT_SMALL, CENTER, Colors::WHITE, getMyCreature()->namePl);
|
||||
new CCreaturePic(159, 4, getMyCreature(), false);
|
||||
new CLabel(78, 11, FONT_SMALL, CENTER, Colors::WHITE, getMyCreature()->namePl);
|
||||
|
||||
Rect sizes(287, 4, 96, 18);
|
||||
values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[190], CGI->generaltexth->fcommands[0], getMyCreature()->Attack()));
|
||||
@ -1660,9 +1664,6 @@ void CFortScreen::RecruitArea::clickRight(tribool down, bool previousState)
|
||||
clickLeft(down, false); //r-click does same as l-click - opens recr. window
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem) :CWindowObject(BORDERED,imagem)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
|
@ -240,12 +240,6 @@ class CHallInterface : public CWindowObject
|
||||
const CBuilding * building;
|
||||
|
||||
ui32 state;//Buildings::EBuildStructure enum
|
||||
|
||||
CAnimImage * picture;
|
||||
CAnimImage * panel;
|
||||
CAnimImage * icon;
|
||||
CLabel * label;
|
||||
|
||||
public:
|
||||
CBuildingBox(int x, int y, const CGTownInstance * Town, const CBuilding * Building);
|
||||
void hover(bool on) override;
|
||||
@ -270,12 +264,8 @@ class CBuildWindow: public CWindowObject
|
||||
const CGTownInstance *town;
|
||||
const CBuilding *building;
|
||||
|
||||
CButton *buy;
|
||||
CButton *cancel;
|
||||
|
||||
std::string getTextForState(int state);
|
||||
void buyFunc();
|
||||
|
||||
public:
|
||||
CBuildWindow(const CGTownInstance *Town, const CBuilding * building, int State, bool rightClick); //c-tor
|
||||
};
|
||||
@ -303,14 +293,10 @@ class CFortScreen : public CWindowObject
|
||||
int level;
|
||||
|
||||
std::string hoverText;
|
||||
CLabel * creatureName;
|
||||
CLabel * dwellingName;
|
||||
CLabel * availableCount;
|
||||
|
||||
std::vector<LabeledValue*> values;
|
||||
CPicture *icons;
|
||||
CAnimImage * buildingPic;
|
||||
CCreaturePic *creatureAnim;
|
||||
|
||||
const CCreature * getMyCreature();
|
||||
const CBuilding * getMyBuilding();
|
||||
|
@ -103,7 +103,7 @@ StackWindowInfo::StackWindowInfo():
|
||||
|
||||
void CStackWindow::CWindowSection::createBackground(std::string path)
|
||||
{
|
||||
background = new CPicture("stackWindow/" + path);
|
||||
CPicture * background = new CPicture("stackWindow/" + path);
|
||||
pos = background->pos;
|
||||
}
|
||||
|
||||
|
@ -49,8 +49,6 @@ class CStackWindow : public CWindowObject
|
||||
{
|
||||
CStackWindow *parent;
|
||||
|
||||
CPicture *background;
|
||||
|
||||
void createBackground(std::string path);
|
||||
void createBonusItem(size_t index, Point position);
|
||||
|
||||
|
@ -792,9 +792,7 @@ CTownItem::CTownItem(const CGTownInstance* Town):
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
|
||||
|
||||
picture = new CAnimImage("ITPT", iconIndex, 0, 5, 6);
|
||||
townArea = new LRClickableAreaOpenTown;
|
||||
townArea->pos = Rect(pos.x+5, pos.y+6, 58, 64);
|
||||
townArea->town = town;
|
||||
new LRClickableAreaOpenTown(Rect(5, 6, 58, 64), town);
|
||||
|
||||
for (size_t i=0; i<town->creatures.size(); i++)
|
||||
{
|
||||
|
@ -33,12 +33,12 @@ class CKingdHeroList;
|
||||
class CKingdTownList;
|
||||
class IInfoBoxData;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Several classes to display basically any data.
|
||||
* Main part - class InfoBox which controls how data will be formatted\positioned
|
||||
* InfoBox have image and 0-2 labels
|
||||
* In constructor it should receive object that implements IInfoBoxData interface
|
||||
*
|
||||
*
|
||||
* interface IInfoBoxData defines way to get data for use in InfoBox
|
||||
* have several implementations:
|
||||
* InfoBoxHeroData - to display one of fields from hero (e.g. absolute value of primary skills)
|
||||
@ -265,7 +265,6 @@ class CTownItem : public CIntObject, public CGarrisonHolder
|
||||
CLabel *name;
|
||||
CLabel *income;
|
||||
CGarrisonInt *garr;
|
||||
LRClickableAreaOpenTown *townArea;
|
||||
|
||||
HeroSlots *heroes;
|
||||
CTownInfo *hall, *fort;
|
||||
@ -338,11 +337,11 @@ private:
|
||||
CLabel * townLabel;
|
||||
CLabel * garrHeroLabel;
|
||||
CLabel * visitHeroLabel;
|
||||
|
||||
|
||||
CIntObject* createTownItem(size_t index);
|
||||
public:
|
||||
CKingdTownList(size_t maxSize);
|
||||
|
||||
|
||||
void townChanged(const CGTownInstance *town);
|
||||
void updateGarrisons() override;
|
||||
};
|
||||
|
@ -529,7 +529,7 @@ CSpellWindow::SpellArea::~SpellArea()
|
||||
|
||||
void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(!down && mySpell)
|
||||
if(mySpell && !down)
|
||||
{
|
||||
int spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero);
|
||||
if(spellCost > owner->myHero->mana) //insufficient mana
|
||||
@ -752,7 +752,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
||||
|
||||
void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && mySpell)
|
||||
if(mySpell && down)
|
||||
{
|
||||
std::string dmgInfo;
|
||||
int causedDmg = owner->myInt->cb->estimateSpellDamage(mySpell, owner->myHero);
|
||||
|
@ -788,13 +788,13 @@ void CTavernWindow::show(SDL_Surface * to)
|
||||
|
||||
void CTavernWindow::HeroPortrait::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(previousState && !down && h)
|
||||
if(h && previousState && !down)
|
||||
*_sel = _id;
|
||||
}
|
||||
|
||||
void CTavernWindow::HeroPortrait::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && h)
|
||||
if(h && down)
|
||||
{
|
||||
GH.pushInt(new CRClickPopupInt(new CHeroWindow(h), true));
|
||||
}
|
||||
@ -1771,11 +1771,10 @@ void CObjectListWindow::init(CIntObject * titlePic, std::string _title, std::str
|
||||
|
||||
if (titlePic)
|
||||
{
|
||||
titleImage = titlePic;
|
||||
addChild(titleImage);
|
||||
titleImage->recActions = defActions;
|
||||
titleImage->pos.x = pos.w/2 + pos.x - titleImage->pos.w/2;
|
||||
titleImage->pos.y =75 + pos.y - titleImage->pos.h/2;
|
||||
addChild(titlePic);
|
||||
titlePic->recActions = defActions;
|
||||
titlePic->pos.x = pos.w/2 + pos.x - titlePic->pos.w/2;
|
||||
titlePic->pos.y =75 + pos.y - titlePic->pos.h/2;
|
||||
}
|
||||
list = new CListBox(std::bind(&CObjectListWindow::genItem, this, _1), CListBox::DestroyFunc(),
|
||||
Point(14, 151), Point(0, 25), 9, items.size(), 0, 1, Rect(262, -32, 256, 256) );
|
||||
|
@ -161,7 +161,6 @@ class CObjectListWindow : public CWindowObject
|
||||
CLabel * descr;
|
||||
|
||||
CListBox * list;
|
||||
CIntObject * titleImage;//title image (castle gate\town portal picture)
|
||||
CButton *ok, *exit;
|
||||
|
||||
std::vector< std::pair<int, std::string> > items;//all items present in list
|
||||
@ -243,7 +242,6 @@ public:
|
||||
|
||||
} *h1, *h2; //recruitable heroes
|
||||
|
||||
CGStatusBar *bar; //tavern's internal status bar
|
||||
int selected;//0 (left) or 1 (right)
|
||||
int oldSelected;//0 (left) or 1 (right)
|
||||
|
||||
|
@ -47,7 +47,6 @@ public:
|
||||
CTextBox *text;
|
||||
std::vector<CButton *> buttons;
|
||||
std::vector<CComponent*> components;
|
||||
CSlider *slider;
|
||||
|
||||
void setDelComps(bool DelComps);
|
||||
virtual void close();
|
||||
|
@ -76,6 +76,9 @@ CArtifact::CArtifact()
|
||||
possibleSlots[ArtBearer::HERO]; //we want to generate map entry even if it will be empty
|
||||
possibleSlots[ArtBearer::CREATURE]; //we want to generate map entry even if it will be empty
|
||||
possibleSlots[ArtBearer::COMMANDER];
|
||||
iconIndex = ArtifactID::NONE;
|
||||
price = 0;
|
||||
aClass = ART_SPECIAL;
|
||||
}
|
||||
|
||||
CArtifact::~CArtifact()
|
||||
@ -1337,17 +1340,6 @@ bool CArtifactSet::isPositionFree(ArtifactPosition pos, bool onlyLockCheck /*= f
|
||||
return true; //no slot means not used
|
||||
}
|
||||
|
||||
si32 CArtifactSet::getArtTypeId(ArtifactPosition pos) const
|
||||
{
|
||||
const CArtifactInstance * const a = getArt(pos);
|
||||
if(!a)
|
||||
{
|
||||
logGlobal->warnStream() << (dynamic_cast<const CGHeroInstance*>(this))->name << " has no artifact at " << pos << " (getArtTypeId)";
|
||||
return -1;
|
||||
}
|
||||
return a->artType->id;
|
||||
}
|
||||
|
||||
ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ArtifactPosition slot)
|
||||
{
|
||||
assert(!vstd::contains(artifactsWorn, slot));
|
||||
|
@ -54,6 +54,12 @@ public:
|
||||
std::string large; // big image for cutom artifacts, used in drag & drop
|
||||
std::string advMapDef; //used for adventure map object
|
||||
si32 iconIndex;
|
||||
ui32 price;
|
||||
std::map<ArtBearer::ArtBearer, std::vector<ArtifactPosition> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
|
||||
std::unique_ptr<std::vector<CArtifact *> > constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
|
||||
std::vector<CArtifact *> constituentOf; // Reverse map of constituents - combined arts that include this art
|
||||
EartClass aClass;
|
||||
ArtifactID id;
|
||||
|
||||
const std::string &Name() const; //getter
|
||||
const std::string &Description() const; //getter
|
||||
@ -68,13 +74,6 @@ public:
|
||||
|
||||
virtual void levelUpArtifact (CArtifactInstance * art){};
|
||||
|
||||
ui32 price;
|
||||
std::map<ArtBearer::ArtBearer, std::vector<ArtifactPosition> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
|
||||
std::unique_ptr<std::vector<CArtifact *> > constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
|
||||
std::vector<CArtifact *> constituentOf; // Reverse map of constituents - combined arts that include this art
|
||||
EartClass aClass;
|
||||
ArtifactID id;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
@ -321,7 +320,6 @@ public:
|
||||
/// Checks if hero possess artifact of given id (either in backack or worn)
|
||||
bool hasArt(ui32 aid, bool onlyWorn = false, bool searchBackpackAssemblies = false) const;
|
||||
bool isPositionFree(ArtifactPosition pos, bool onlyLockCheck = false) const;
|
||||
si32 getArtTypeId(ArtifactPosition pos) const;
|
||||
|
||||
virtual ArtBearer::ArtBearer bearerType() const = 0;
|
||||
virtual ~CArtifactSet() = default;
|
||||
|
@ -356,7 +356,9 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(con
|
||||
return ESpellCastProblem::INVALID;
|
||||
}
|
||||
const PlayerColor player = caster->getOwner();
|
||||
const ui8 side = playerToSide(player);
|
||||
const si8 side = playerToSide(player);
|
||||
if(side < 0)
|
||||
return ESpellCastProblem::INVALID;
|
||||
if(!battleDoWeKnowAbout(side))
|
||||
{
|
||||
logGlobal->warnStream() << "You can't check if enemy can cast given spell!";
|
||||
@ -391,7 +393,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(con
|
||||
bool CBattleInfoEssentials::battleCanFlee(PlayerColor player) const
|
||||
{
|
||||
RETURN_IF_NOT_BATTLE(false);
|
||||
ui8 mySide = playerToSide(player);
|
||||
const si8 mySide = playerToSide(player);
|
||||
const CGHeroInstance *myHero = battleGetFightingHero(mySide);
|
||||
|
||||
//current player have no hero
|
||||
@ -413,7 +415,7 @@ bool CBattleInfoEssentials::battleCanFlee(PlayerColor player) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ui8 CBattleInfoEssentials::playerToSide(PlayerColor player) const
|
||||
si8 CBattleInfoEssentials::playerToSide(PlayerColor player) const
|
||||
{
|
||||
RETURN_IF_NOT_BATTLE(-1);
|
||||
int ret = vstd::find_pos_if(getBattle()->sides, [=](const SideInBattle &side){ return side.color == player; });
|
||||
@ -426,8 +428,8 @@ ui8 CBattleInfoEssentials::playerToSide(PlayerColor player) const
|
||||
bool CBattleInfoEssentials::playerHasAccessToHeroInfo(PlayerColor player, const CGHeroInstance * h) const
|
||||
{
|
||||
RETURN_IF_NOT_BATTLE(false);
|
||||
ui8 playerSide = playerToSide(player);
|
||||
if (playerSide != (ui8)-1)
|
||||
const si8 playerSide = playerToSide(player);
|
||||
if (playerSide > 0)
|
||||
{
|
||||
if (getBattle()->sides[!playerSide].hero == h)
|
||||
return true;
|
||||
@ -1714,7 +1716,11 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
|
||||
return ESpellCastProblem::INVALID;
|
||||
}
|
||||
const PlayerColor player = caster->getOwner();
|
||||
const ui8 side = playerToSide(player);
|
||||
const si8 side = playerToSide(player);
|
||||
|
||||
if(side < 0)
|
||||
return ESpellCastProblem::INVALID;
|
||||
|
||||
if(!battleDoWeKnowAbout(side))
|
||||
return ESpellCastProblem::INVALID;
|
||||
|
||||
@ -1727,7 +1733,12 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
|
||||
case ECastingMode::HERO_CASTING:
|
||||
{
|
||||
const CGHeroInstance * castingHero = dynamic_cast<const CGHeroInstance *>(caster);//todo: unify hero|creature spell cost
|
||||
assert(castingHero);
|
||||
if(!castingHero)
|
||||
{
|
||||
logGlobal->error("battleCanCastThisSpell: invalid caster");
|
||||
return ESpellCastProblem::INVALID;
|
||||
}
|
||||
|
||||
if(!castingHero->getArt(ArtifactPosition::SPELLBOOK))
|
||||
return ESpellCastProblem::NO_SPELLBOOK;
|
||||
if(!castingHero->canCastThisSpell(spell))
|
||||
@ -1994,13 +2005,17 @@ int CBattleInfoCallback::battleGetSurrenderCost(PlayerColor Player) const
|
||||
if(!battleCanSurrender(Player))
|
||||
return -1;
|
||||
|
||||
const si8 playerSide = playerToSide(Player);
|
||||
if(playerSide < 0)
|
||||
return -1;
|
||||
|
||||
int ret = 0;
|
||||
double discount = 0;
|
||||
for(const CStack *s : battleAliveStacks(playerToSide(Player)))
|
||||
for(const CStack *s : battleAliveStacks(playerSide))
|
||||
if(s->base) //we pay for our stack that comes from our army slots - condition eliminates summoned cres and war machines
|
||||
ret += s->getCreature()->cost[Res::GOLD] * s->count;
|
||||
|
||||
if(const CGHeroInstance *h = battleGetFightingHero(playerToSide(Player)))
|
||||
if(const CGHeroInstance *h = battleGetFightingHero(playerSide))
|
||||
discount += h->valOfBonuses(Bonus::SURRENDER_DISCOUNT);
|
||||
|
||||
ret *= (100.0 - discount) / 100.0;
|
||||
|
@ -189,7 +189,7 @@ public:
|
||||
si8 battleGetTacticsSide() const; //returns which side is in tactics phase, undefined if none (?)
|
||||
bool battleCanFlee(PlayerColor player) const;
|
||||
bool battleCanSurrender(PlayerColor player) const;
|
||||
ui8 playerToSide(PlayerColor player) const;
|
||||
si8 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;
|
||||
|
@ -105,9 +105,15 @@ si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatur
|
||||
|
||||
CCreature::CCreature()
|
||||
{
|
||||
doubleWide = false;
|
||||
setNodeType(CBonusSystemNode::CREATURE);
|
||||
faction = 0;
|
||||
level = 0;
|
||||
fightValue = AIValue = growth = hordeGrowth = ammMin = ammMax = 0;
|
||||
doubleWide = false;
|
||||
special = true;
|
||||
iconIndex = -1;
|
||||
}
|
||||
|
||||
void CCreature::addBonus(int val, Bonus::BonusType type, int subtype /*= -1*/)
|
||||
{
|
||||
auto added = std::make_shared<Bonus>(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
|
||||
|
@ -656,6 +656,7 @@ CGameState::CGameState()
|
||||
//objCaller = new CObjectCallersHandler;
|
||||
globalEffects.setDescription("Global effects");
|
||||
globalEffects.setNodeType(CBonusSystemNode::GLOBAL_EFFECTS);
|
||||
day = 0;
|
||||
}
|
||||
|
||||
CGameState::~CGameState()
|
||||
@ -2866,8 +2867,8 @@ CGHeroInstance * CGameState::getUsedHero(HeroTypeID hid) const
|
||||
}
|
||||
|
||||
PlayerState::PlayerState()
|
||||
: color(-1), enteredWinningCheatCode(0),
|
||||
enteredLosingCheatCode(0), status(EPlayerStatus::INGAME)
|
||||
: color(-1), human(false), enteredWinningCheatCode(false),
|
||||
enteredLosingCheatCode(false), status(EPlayerStatus::INGAME)
|
||||
{
|
||||
setNodeType(PLAYER);
|
||||
}
|
||||
@ -2933,6 +2934,7 @@ void InfoAboutArmy::initFromArmy(const CArmedInstance *Army, bool detailed)
|
||||
|
||||
void InfoAboutHero::assign(const InfoAboutHero & iah)
|
||||
{
|
||||
vstd::clear_pointer(details);
|
||||
InfoAboutArmy::operator = (iah);
|
||||
|
||||
details = (iah.details ? new Details(*iah.details) : nullptr);
|
||||
@ -2962,7 +2964,7 @@ InfoAboutHero::InfoAboutHero(const CGHeroInstance *h, InfoAboutHero::EInfoLevel
|
||||
|
||||
InfoAboutHero::~InfoAboutHero()
|
||||
{
|
||||
delete details;
|
||||
vstd::clear_pointer(details);
|
||||
}
|
||||
|
||||
InfoAboutHero & InfoAboutHero::operator=(const InfoAboutHero & iah)
|
||||
@ -2973,6 +2975,7 @@ InfoAboutHero & InfoAboutHero::operator=(const InfoAboutHero & iah)
|
||||
|
||||
void InfoAboutHero::initFromHero(const CGHeroInstance *h, InfoAboutHero::EInfoLevel infoLevel)
|
||||
{
|
||||
vstd::clear_pointer(details);
|
||||
if(!h)
|
||||
return;
|
||||
|
||||
@ -3013,14 +3016,18 @@ InfoAboutTown::InfoAboutTown():
|
||||
|
||||
}
|
||||
|
||||
InfoAboutTown::InfoAboutTown(const CGTownInstance *t, bool detailed)
|
||||
InfoAboutTown::InfoAboutTown(const CGTownInstance *t, bool detailed):
|
||||
details(nullptr),
|
||||
tType(nullptr),
|
||||
built(0),
|
||||
fortLevel(0)
|
||||
{
|
||||
initFromTown(t, detailed);
|
||||
}
|
||||
|
||||
InfoAboutTown::~InfoAboutTown()
|
||||
{
|
||||
delete details;
|
||||
vstd::clear_pointer(details);
|
||||
}
|
||||
|
||||
void InfoAboutTown::initFromTown(const CGTownInstance *t, bool detailed)
|
||||
@ -3032,6 +3039,8 @@ void InfoAboutTown::initFromTown(const CGTownInstance *t, bool detailed)
|
||||
name = t->name;
|
||||
tType = t->town;
|
||||
|
||||
vstd::clear_pointer(details);
|
||||
|
||||
if(detailed)
|
||||
{
|
||||
//include details about hero
|
||||
|
@ -173,7 +173,9 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
||||
const CGObjectInstance * obj; //related object, most likely Seer Hut
|
||||
int3 tile;
|
||||
|
||||
QuestInfo(){};
|
||||
QuestInfo()
|
||||
: quest(nullptr), obj(nullptr), tile(-1,-1,-1)
|
||||
{};
|
||||
QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) :
|
||||
quest (Quest), obj (Obj), tile (Tile){};
|
||||
|
||||
|
@ -59,7 +59,7 @@ EAlignment::EAlignment CHeroClass::getAlignment() const
|
||||
}
|
||||
|
||||
CHeroClass::CHeroClass()
|
||||
: commander(nullptr)
|
||||
: faction(0), id(0), affinity(0), defaultTavernChance(0), commander(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -486,12 +486,22 @@ JsonNode addMeta(JsonNode config, std::string meta)
|
||||
return config;
|
||||
}
|
||||
|
||||
CModInfo::CModInfo():
|
||||
checksum(0),
|
||||
enabled(false),
|
||||
validation(PENDING)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CModInfo::CModInfo(std::string identifier,const JsonNode & local, const JsonNode & config):
|
||||
identifier(identifier),
|
||||
name(config["name"].String()),
|
||||
description(config["description"].String()),
|
||||
dependencies(config["depends"].convertTo<std::set<std::string> >()),
|
||||
conflicts(config["conflicts"].convertTo<std::set<std::string> >()),
|
||||
checksum(0),
|
||||
enabled(false),
|
||||
validation(PENDING),
|
||||
config(addMeta(config, identifier))
|
||||
{
|
||||
@ -554,6 +564,10 @@ void CModInfo::loadLocalData(const JsonNode & data)
|
||||
|
||||
CModHandler::CModHandler()
|
||||
{
|
||||
modules.COMMANDERS = false;
|
||||
modules.STACK_ARTIFACT = false;
|
||||
modules.STACK_EXP = false;
|
||||
modules.MITHRIL = false;
|
||||
for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)
|
||||
{
|
||||
identifiers.registerObject("core", "resource", GameConstants::RESOURCE_NAMES[i], i);
|
||||
|
@ -191,7 +191,7 @@ public:
|
||||
|
||||
JsonNode config;
|
||||
|
||||
CModInfo(){}
|
||||
CModInfo();
|
||||
CModInfo(std::string identifier, const JsonNode & local, const JsonNode & config);
|
||||
|
||||
JsonNode saveLocalData() const;
|
||||
|
@ -43,6 +43,11 @@ CPathfinder::CPathfinder(CPathsInfo & _out, CGameState * _gs, const CGHeroInstan
|
||||
assert(hero);
|
||||
assert(hero == getHero(hero->id));
|
||||
|
||||
cp = dp = nullptr;
|
||||
ct = dt = nullptr;
|
||||
ctObj = dtObj = nullptr;
|
||||
destAction = CGPathNode::UNKNOWN;
|
||||
|
||||
out.hero = hero;
|
||||
out.hpos = hero->getPosition(false);
|
||||
if(!isInTheMap(out.hpos)/* || !gs->map->isInTheMap(dest)*/) //check input
|
||||
|
@ -26,6 +26,12 @@
|
||||
|
||||
const int NAMES_PER_TOWN=16; // number of town names per faction in H3 files. Json can define any number
|
||||
|
||||
CBuilding::CBuilding():
|
||||
town(nullptr),mode(BUILD_NORMAL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const std::string & CBuilding::Name() const
|
||||
{
|
||||
return name;
|
||||
@ -64,6 +70,8 @@ si32 CBuilding::getDistance(BuildingID buildID) const
|
||||
CFaction::CFaction()
|
||||
{
|
||||
town = nullptr;
|
||||
index = 0;
|
||||
alignment = EAlignment::NEUTRAL;
|
||||
}
|
||||
|
||||
CFaction::~CFaction()
|
||||
@ -72,6 +80,7 @@ CFaction::~CFaction()
|
||||
}
|
||||
|
||||
CTown::CTown()
|
||||
: faction(nullptr), mageLevel(0), primaryRes(0), moatDamage(0), defaultTavernChance(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ public:
|
||||
BUILD_GRAIL // 3 - grail - building reqires grail to be built
|
||||
} mode;
|
||||
|
||||
CBuilding();
|
||||
|
||||
const std::string &Name() const;
|
||||
const std::string &Description() const;
|
||||
|
||||
|
@ -17,15 +17,14 @@ template <typename T> struct CondSh
|
||||
boost::condition_variable cond;
|
||||
boost::mutex mx;
|
||||
|
||||
CondSh() {}
|
||||
CondSh(T t) : data(t) {}
|
||||
|
||||
// set data
|
||||
void set(T t)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mx);
|
||||
boost::unique_lock<boost::mutex> lock(mx);
|
||||
data = t;
|
||||
}
|
||||
}
|
||||
|
||||
// set data and notify
|
||||
void setn(T t)
|
||||
@ -37,7 +36,7 @@ template <typename T> struct CondSh
|
||||
// get stored value
|
||||
T get()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mx);
|
||||
boost::unique_lock<boost::mutex> lock(mx);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -1329,6 +1329,7 @@ bool IPropagator::shouldBeAttached(CBonusSystemNode *dest)
|
||||
}
|
||||
|
||||
CPropagatorNodeType::CPropagatorNodeType()
|
||||
:nodeType(0)
|
||||
{
|
||||
|
||||
}
|
||||
@ -1349,6 +1350,7 @@ CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter(int TerrainType)
|
||||
}
|
||||
|
||||
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter()
|
||||
: terrainType(-1)
|
||||
{
|
||||
|
||||
}
|
||||
@ -1366,6 +1368,7 @@ CreatureFactionLimiter::CreatureFactionLimiter(int Faction)
|
||||
}
|
||||
|
||||
CreatureFactionLimiter::CreatureFactionLimiter()
|
||||
: faction(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1376,6 +1379,7 @@ int CreatureFactionLimiter::limit(const BonusLimitationContext &context) const
|
||||
}
|
||||
|
||||
CreatureAlignmentLimiter::CreatureAlignmentLimiter()
|
||||
: alignment(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,7 @@ struct Component
|
||||
h & id & subtype & val & when;
|
||||
}
|
||||
Component()
|
||||
:id(0), subtype(0), val(0), when(0)
|
||||
{
|
||||
}
|
||||
DLL_LINKAGE explicit Component(const CStackBasicDescriptor &stack);
|
||||
|
@ -1688,6 +1688,7 @@ DLL_LINKAGE void ObstaclesRemoved::applyGs(CGameState *gs)
|
||||
|
||||
DLL_LINKAGE CatapultAttack::CatapultAttack()
|
||||
{
|
||||
attacker = -1;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CatapultAttack::~CatapultAttack()
|
||||
|
@ -125,8 +125,6 @@ void LibClasses::init()
|
||||
|
||||
//FIXME: make sure that everything is ok after game restart
|
||||
//TODO: This should be done every time mod config changes
|
||||
|
||||
IS_AI_ENABLED = false;
|
||||
}
|
||||
|
||||
void LibClasses::clear()
|
||||
@ -164,6 +162,7 @@ void LibClasses::makeNull()
|
||||
|
||||
LibClasses::LibClasses()
|
||||
{
|
||||
IS_AI_ENABLED = false;
|
||||
//init pointers to handlers
|
||||
makeNull();
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ class DLL_LINKAGE LibClasses
|
||||
void callWhenDeserializing(); //should be called only by serialize !!!
|
||||
void makeNull(); //sets all handler pointers to null
|
||||
public:
|
||||
bool IS_AI_ENABLED; //VLC is the only object visible from both CMT and GeniusAI
|
||||
|
||||
bool IS_AI_ENABLED; //unused?
|
||||
|
||||
const IBonusTypeHandler * getBth() const;
|
||||
|
||||
CArtHandler * arth;
|
||||
|
@ -229,7 +229,8 @@ bool FileStream::CreateFile(const boost::filesystem::path& filename)
|
||||
{
|
||||
FILE* f = do_open(filename.c_str(), CHAR_LITERAL("wb"));
|
||||
bool result = (f != nullptr);
|
||||
fclose(f);
|
||||
if(result)
|
||||
fclose(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ static std::string & visitedTxt(const bool visited)
|
||||
|
||||
CBank::CBank()
|
||||
{
|
||||
daycounter = 0;
|
||||
resetDuration = 0;
|
||||
}
|
||||
|
||||
CBank::~CBank()
|
||||
|
@ -34,6 +34,13 @@ static void showInfoDialog(const CGHeroInstance* h, const ui32 txtID, const ui16
|
||||
showInfoDialog(playerID,txtID,soundID);
|
||||
}
|
||||
|
||||
CGPandoraBox::CGPandoraBox()
|
||||
: hasGuardians(false), gainedExp(0), manaDiff(0), moraleDiff(0), luckDiff(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CGPandoraBox::initObj(CRandomGenerator & rand)
|
||||
{
|
||||
blockVisit = (ID==Obj::PANDORAS_BOX); //block only if it's really pandora's box (events also derive from that class)
|
||||
@ -362,6 +369,12 @@ void CGPandoraBox::afterSuccessfulVisit() const
|
||||
cb->removeAfterVisit(this);
|
||||
}
|
||||
|
||||
CGEvent::CGEvent()
|
||||
: CGPandoraBox(), removeAfterVisit(false), availableFor(0), computerActivate(false), humanActivate(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGEvent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(!(availableFor & (1 << h->tempOwner.getNum())))
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
std::vector<SpellID> spells; //gained spells
|
||||
CCreatureSet creatures; //gained creatures
|
||||
|
||||
CGPandoraBox() : gainedExp(0), manaDiff(0), moraleDiff(0), luckDiff(0){};
|
||||
CGPandoraBox();
|
||||
void initObj(CRandomGenerator & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
@ -71,7 +71,7 @@ public:
|
||||
h & removeAfterVisit & availableFor & computerActivate & humanActivate;
|
||||
}
|
||||
|
||||
CGEvent() : CGPandoraBox(){};
|
||||
CGEvent();
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
private:
|
||||
void activated(const CGHeroInstance * h) const;
|
||||
|
@ -370,7 +370,6 @@ CGTownInstance::EFortLevel CGTownInstance::fortLevel() const //0 - none, 1 - for
|
||||
|
||||
int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
|
||||
{
|
||||
|
||||
if (hasBuilt(BuildingID::CAPITOL))
|
||||
return 3;
|
||||
if (hasBuilt(BuildingID::CITY_HALL))
|
||||
@ -381,6 +380,7 @@ int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - c
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CGTownInstance::mageGuildLevel() const
|
||||
{
|
||||
if (hasBuilt(BuildingID::MAGES_GUILD_5))
|
||||
|
@ -357,6 +357,17 @@ std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const
|
||||
return objects.at(type)->handlerName;
|
||||
}
|
||||
|
||||
AObjectTypeHandler::AObjectTypeHandler():
|
||||
type(-1), subtype(-1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AObjectTypeHandler::~AObjectTypeHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AObjectTypeHandler::setType(si32 type, si32 subtype)
|
||||
{
|
||||
this->type = type;
|
||||
|
@ -118,8 +118,8 @@ public:
|
||||
|
||||
si32 type;
|
||||
si32 subtype;
|
||||
|
||||
virtual ~AObjectTypeHandler(){}
|
||||
AObjectTypeHandler();
|
||||
virtual ~AObjectTypeHandler();
|
||||
|
||||
void setType(si32 type, si32 subtype);
|
||||
void setTypeName(std::string type, std::string subtype);
|
||||
|
@ -454,6 +454,7 @@ void CRewardableObject::newTurn(CRandomGenerator & rand) const
|
||||
CRewardableObject::CRewardableObject():
|
||||
soundID(soundBase::invalid),
|
||||
selectMode(0),
|
||||
visitMode(0),
|
||||
selectedReward(0),
|
||||
resetDuration(0),
|
||||
canRefuse(false)
|
||||
|
@ -87,6 +87,7 @@ void CTownInstanceConstructor::configureObject(CGObjectInstance * object, CRando
|
||||
}
|
||||
|
||||
CHeroInstanceConstructor::CHeroInstanceConstructor()
|
||||
:heroClass(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
@ -257,7 +258,9 @@ std::vector<const CCreature *> CDwellingInstanceConstructor::getProducedCreature
|
||||
}
|
||||
|
||||
CBankInstanceConstructor::CBankInstanceConstructor()
|
||||
: bankResetDuration(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CBankInstanceConstructor::initTypeData(const JsonNode & input)
|
||||
|
@ -127,7 +127,6 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
||||
ms.addTxt(MetaString::GENERAL_TXT,243);
|
||||
break;
|
||||
default: //decision = cost in gold
|
||||
VLC->generaltexth->allTexts[244];
|
||||
ms << boost::to_string(boost::format(VLC->generaltexth->allTexts[244]) % decision);
|
||||
break;
|
||||
}
|
||||
@ -237,7 +236,7 @@ void CGCreature::initObj(CRandomGenerator & rand)
|
||||
}
|
||||
}
|
||||
|
||||
temppower = stacks[SlotID(0)]->count * 1000;
|
||||
temppower = stacks[SlotID(0)]->count * (ui64)1000;
|
||||
refusedJoining = false;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ public:
|
||||
EBonusType bonusType;
|
||||
ui16 bonusID; //ID of skill/spell
|
||||
|
||||
CGScholar() : bonusType(EBonusType::RANDOM){};
|
||||
CGScholar() : bonusType(EBonusType::RANDOM),bonusID(0){};
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void initObj(CRandomGenerator & rand) override;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
|
@ -217,7 +217,9 @@ CMapHeader::~CMapHeader()
|
||||
|
||||
}
|
||||
|
||||
CMap::CMap() : checksum(0), grailPos(-1, -1, -1), grailRadius(0), terrain(nullptr)
|
||||
CMap::CMap()
|
||||
: checksum(0), grailPos(-1, -1, -1), grailRadius(0), terrain(nullptr),
|
||||
guardingCreaturePositions(nullptr)
|
||||
{
|
||||
allHeroes.resize(allowedHeroes.size());
|
||||
allowedAbilities = VLC->heroh->getDefaultAllowedAbilities();
|
||||
|
@ -37,7 +37,9 @@ void CMapGenerator::foreachDirectNeighbour(const int3& pos, std::function<void(i
|
||||
|
||||
|
||||
CMapGenerator::CMapGenerator() :
|
||||
zonesTotal(0), monolithIndex(0)
|
||||
mapGenOptions(nullptr), randomSeed(0), editManager(nullptr),
|
||||
zonesTotal(0), tiles(nullptr), prisonsRemaining(0),
|
||||
monolithIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -639,7 +641,7 @@ void CMapGenerator::createConnections2()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!continueOuterLoop) //we didn't find ANY tile - break outer loop
|
||||
if (!continueOuterLoop) //we didn't find ANY tile - break outer loop
|
||||
break;
|
||||
}
|
||||
if (!guardPos.valid()) //cleanup? is this safe / enough?
|
||||
@ -751,7 +753,7 @@ TRmgTemplateZoneId CMapGenerator::getZoneID(const int3& tile) const
|
||||
return zoneColouring[tile.z][tile.x][tile.y];
|
||||
}
|
||||
|
||||
void CMapGenerator::setZoneID(const int3& tile, TRmgTemplateZoneId zid)
|
||||
void CMapGenerator::setZoneID(const int3& tile, TRmgTemplateZoneId zid)
|
||||
{
|
||||
checkIsOnMap(tile);
|
||||
|
||||
|
@ -24,7 +24,9 @@ CPlacedZone::CPlacedZone(const CRmgTemplateZone * zone)
|
||||
|
||||
}
|
||||
|
||||
CZonePlacer::CZonePlacer(CMapGenerator * Gen) : gen(Gen)
|
||||
CZonePlacer::CZonePlacer(CMapGenerator * Gen)
|
||||
: width(0), height(0), scaleX(0), scaleY(0), mapSize(0), gravityConstant(0), stiffnessConstant(0),
|
||||
gen(Gen)
|
||||
{
|
||||
|
||||
}
|
||||
@ -153,7 +155,7 @@ void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenera
|
||||
}
|
||||
|
||||
void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, CRandomGenerator * rand)
|
||||
{
|
||||
{
|
||||
std::vector<float> totalSize = { 0, 0 }; //make sure that sum of zone sizes on surface and uderground match size of the map
|
||||
|
||||
const float radius = 0.4f;
|
||||
@ -168,7 +170,7 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
||||
|
||||
//first pass - determine fixed surface for zones
|
||||
for (auto zone : zonesVector)
|
||||
{
|
||||
{
|
||||
if (!underground) //this step is ignored
|
||||
zonesToPlace.push_back(zone);
|
||||
else //place players depending on their factions
|
||||
|
@ -370,7 +370,7 @@ ESpellCastProblem::ESpellCastProblem EarthquakeMechanics::canBeCast(const CBattl
|
||||
if(ti.smart)
|
||||
{
|
||||
//if spell targeting is smart, then only attacker can use it
|
||||
if(cb->playerToSide(caster->getOwner()) != 0)
|
||||
if(cb->playerToSide(caster->getOwner()) != BattleSide::ATTACKER)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
}
|
||||
|
||||
@ -406,7 +406,9 @@ ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const I
|
||||
///ObstacleMechanics
|
||||
ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||
{
|
||||
ui8 side = cb->playerToSide(ctx.caster->getOwner());
|
||||
const si8 side = cb->playerToSide(ctx.caster->getOwner());
|
||||
if(side < 0)
|
||||
return ESpellCastProblem::INVALID;
|
||||
|
||||
bool hexesOutsideBattlefield = false;
|
||||
|
||||
@ -496,7 +498,11 @@ void PatchObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env
|
||||
ESpellCastProblem::ESpellCastProblem LandMineMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
||||
{
|
||||
//LandMine are useless if enemy has native stack and can see mines, check for LandMine damage immunity is done in general way by CSpell
|
||||
const ui8 otherSide = !cb->playerToSide(caster->getOwner());
|
||||
const si8 playerSide = cb->playerToSide(caster->getOwner());
|
||||
if(playerSide < 0)
|
||||
return ESpellCastProblem::INVALID;
|
||||
|
||||
const si8 otherSide = !playerSide;
|
||||
|
||||
if(cb->battleHasNativeStack(otherSide))
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
|
@ -635,8 +635,10 @@ std::vector<const CStack *> DefaultSpellMechanics::calculateAffectedStacks(const
|
||||
{
|
||||
std::set<const CStack* > attackedCres;//std::set to exclude multiple occurrences of two hex creatures
|
||||
|
||||
const ui8 attackerSide = cb->playerToSide(ctx.caster->getOwner()) == 1;
|
||||
auto attackedHexes = rangeInHexes(ctx.destination, ctx.schoolLvl, attackerSide);
|
||||
const si8 playerSide = cb->playerToSide(ctx.caster->getOwner());
|
||||
if(playerSide < 0)
|
||||
return std::vector<const CStack *>();
|
||||
auto attackedHexes = rangeInHexes(ctx.destination, ctx.schoolLvl, playerSide);
|
||||
|
||||
//hackfix for banned creature massive spells
|
||||
if(!ctx.ti.massive && owner->getLevelInfo(ctx.schoolLvl).range == "X")
|
||||
|
@ -95,10 +95,11 @@ CSpell::LevelInfo::~LevelInfo()
|
||||
///CSpell
|
||||
CSpell::CSpell():
|
||||
id(SpellID::NONE), level(0),
|
||||
power(0),
|
||||
combatSpell(false), creatureAbility(false),
|
||||
positiveness(ESpellPositiveness::NEUTRAL),
|
||||
defaultProbability(0),
|
||||
isRising(false), isDamage(false), isOffensive(false),
|
||||
isRising(false), isDamage(false), isOffensive(false), isSpecial(true),
|
||||
targetType(ETargetType::NO_TARGET),
|
||||
mechanics(),
|
||||
adventureMechanics()
|
||||
|
@ -75,7 +75,7 @@ private:
|
||||
mutable CGameHandler * gh;
|
||||
};
|
||||
|
||||
CondSh<bool> battleMadeAction;
|
||||
CondSh<bool> battleMadeAction(false);
|
||||
CondSh<BattleResult *> battleResult(nullptr);
|
||||
template <typename T> class CApplyOnGH;
|
||||
|
||||
@ -947,11 +947,13 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
|
||||
{
|
||||
logGlobal->error("Received a null package marked as request %d from player %d", requestID, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
packType = typeList.getTypeID(pack); //get the id of type
|
||||
|
||||
packType = typeList.getTypeID(pack); //get the id of type
|
||||
|
||||
logGlobal->trace("Received client message (request %d by player %d (%s)) of type with ID=%d (%s).\n",
|
||||
requestID, player, player.getStr(), packType, typeid(*pack).name());
|
||||
logGlobal->trace("Received client message (request %d by player %d (%s)) of type with ID=%d (%s).\n",
|
||||
requestID, player, player.getStr(), packType, typeid(*pack).name());
|
||||
}
|
||||
}
|
||||
|
||||
//prepare struct informing that action was applied
|
||||
@ -2148,7 +2150,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
|
||||
const CGTownInstance *t = getTown(dstid);
|
||||
|
||||
if (!h || !t || h->getOwner() != gs->currentPlayer)
|
||||
logGlobal->error("Invalid call to teleportHero!");
|
||||
COMPLAIN_RET("Invalid call to teleportHero!");
|
||||
|
||||
const CGTownInstance *from = h->visitedTown;
|
||||
if (((h->getOwner() != t->getOwner())
|
||||
@ -2173,11 +2175,11 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner)
|
||||
std::set<PlayerColor> playerColors = {owner, oldOwner};
|
||||
checkVictoryLossConditions(playerColors);
|
||||
|
||||
if (dynamic_cast<const CGTownInstance *>(obj)) //town captured
|
||||
const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(obj);
|
||||
if (town) //town captured
|
||||
{
|
||||
if (owner < PlayerColor::PLAYER_LIMIT) //new owner is real player
|
||||
{
|
||||
const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(obj);
|
||||
if (town->hasBuilt(BuildingID::PORTAL_OF_SUMMON, ETownType::DUNGEON))
|
||||
setPortalDwelling(town, true, false);
|
||||
}
|
||||
@ -2238,6 +2240,7 @@ void CGameHandler::giveResources(PlayerColor player, TResources resources)
|
||||
sr.abs = false;
|
||||
sr.player = player;
|
||||
sr.res = resources;
|
||||
sendAndApply(&sr);
|
||||
}
|
||||
|
||||
void CGameHandler::giveCreatures(const CArmedInstance *obj, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove)
|
||||
@ -3327,6 +3330,9 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid)
|
||||
|
||||
bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID aid)
|
||||
{
|
||||
if(!h)
|
||||
COMPLAIN_RET("Only hero can buy artifacts!");
|
||||
|
||||
if (!vstd::contains(m->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), aid))
|
||||
COMPLAIN_RET("That artifact is unavailable!");
|
||||
|
||||
@ -3374,11 +3380,10 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::E
|
||||
|
||||
bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, Res::ERes rid)
|
||||
{
|
||||
COMPLAIN_RET_FALSE_IF((!h), "Only hero can sell artifacts!");
|
||||
const CArtifactInstance *art = h->getArtByInstanceId(aid);
|
||||
if (!art)
|
||||
COMPLAIN_RET("There is no artifact to sell!");
|
||||
if (!art->artType->isTradable())
|
||||
COMPLAIN_RET("Cannot sell a war machine or spellbook!");
|
||||
COMPLAIN_RET_FALSE_IF((!art), "There is no artifact to sell!");
|
||||
COMPLAIN_RET_FALSE_IF((!art->artType->isTradable()), "Cannot sell a war machine or spellbook!");
|
||||
|
||||
int resVal = 0, dump = 1;
|
||||
m->getOffer(art->artType->id, rid, dump, resVal, EMarketMode::ARTIFACT_RESOURCE);
|
||||
@ -3388,14 +3393,6 @@ bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, Artif
|
||||
return true;
|
||||
}
|
||||
|
||||
//void CGameHandler::lootArtifacts (TArtHolder source, TArtHolder dest, std::vector<ui32> &arts)
|
||||
//{
|
||||
// //const CGHeroInstance * h1 = dynamic_cast<CGHeroInstance *> source;
|
||||
// //auto s = boost::apply_visitor(GetArtifactSetPtr(), source);
|
||||
// {
|
||||
// }
|
||||
//}
|
||||
|
||||
bool CGameHandler::buySecSkill(const IMarket *m, const CGHeroInstance *h, SecondarySkill skill)
|
||||
{
|
||||
if (!h)
|
||||
@ -3445,6 +3442,8 @@ bool CGameHandler::tradeResources(const IMarket *market, ui32 val, PlayerColor p
|
||||
|
||||
bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID)
|
||||
{
|
||||
if(!hero)
|
||||
COMPLAIN_RET("Only hero can sell creatures!");
|
||||
if (!vstd::contains(hero->Slots(), slot))
|
||||
COMPLAIN_RET("Hero doesn't have any creature in that slot!");
|
||||
|
||||
@ -4488,6 +4487,7 @@ void CGameHandler::handleDamageFromObstacle(const CObstacleInstance &obstacle, c
|
||||
|
||||
//helper info
|
||||
const SpellCreatedObstacle *spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(&obstacle); //not nice but we may need spell params
|
||||
|
||||
const ui8 side = !curStack->attackerOwned; //if enemy is defending (false = 0), side of enemy hero is 1 (true)
|
||||
const CGHeroInstance *hero = gs->curB->battleGetFightingHero(side);//FIXME: there may be no hero - landmines in Tower
|
||||
|
||||
@ -4497,6 +4497,7 @@ void CGameHandler::handleDamageFromObstacle(const CObstacleInstance &obstacle, c
|
||||
}
|
||||
else if (obstacle.obstacleType == CObstacleInstance::LAND_MINE)
|
||||
{
|
||||
COMPLAIN_RET_IF((!spellObstacle), "Invalid obstacle instance");
|
||||
//You don't get hit by a Mine you can see.
|
||||
if (gs->curB->battleIsObstacleVisibleForSide(obstacle, (BattlePerspective::BattlePerspective)side))
|
||||
return;
|
||||
@ -4516,6 +4517,7 @@ void CGameHandler::handleDamageFromObstacle(const CObstacleInstance &obstacle, c
|
||||
}
|
||||
else if (obstacle.obstacleType == CObstacleInstance::FIRE_WALL)
|
||||
{
|
||||
COMPLAIN_RET_IF((!spellObstacle), "Invalid obstacle instance");
|
||||
const CSpell * sp = SpellID(SpellID::FIRE_WALL).toSpell();
|
||||
|
||||
if (sp->isImmuneByStack(hero, curStack))
|
||||
@ -5250,6 +5252,9 @@ void CGameHandler::visitObjectOnTile(const TerrainTile &t, const CGHeroInstance
|
||||
|
||||
bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, SlotID slot, ui32 count)
|
||||
{
|
||||
if (!hero)
|
||||
COMPLAIN_RET("You need hero to sacrifice creature!");
|
||||
|
||||
int oldCount = hero->getStackCount(slot);
|
||||
|
||||
if (oldCount < count)
|
||||
@ -5271,15 +5276,21 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc
|
||||
|
||||
bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition slot)
|
||||
{
|
||||
if (!hero)
|
||||
COMPLAIN_RET("You need hero to sacrifice artifact!");
|
||||
|
||||
ArtifactLocation al(hero, slot);
|
||||
const CArtifactInstance *a = al.getArt();
|
||||
|
||||
if (!a)
|
||||
COMPLAIN_RET("Cannot find artifact to sacrifice!");
|
||||
|
||||
COMPLAIN_RET_FALSE_IF(!a,"Cannot find artifact to sacrifice!");
|
||||
|
||||
int dmp, expToGive;
|
||||
m->getOffer(hero->getArtTypeId(slot), 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);
|
||||
const CArtifactInstance * art = hero->getArt(slot);
|
||||
COMPLAIN_RET_FALSE_IF((!art), "No artifact at position to sacrifice!");
|
||||
|
||||
si32 typId = art->artType->id;
|
||||
|
||||
m->getOffer(typId, 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);
|
||||
|
||||
removeArtifact(al);
|
||||
changePrimSkill(hero, PrimarySkill::EXPERIENCE, expToGive);
|
||||
@ -6275,6 +6286,8 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const
|
||||
CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
||||
{
|
||||
winnerHero = loserHero = nullptr;
|
||||
duel = false;
|
||||
remainingBattleQueriesCount = 0;
|
||||
}
|
||||
|
||||
CRandomGenerator & CGameHandler::getRandomGenerator()
|
||||
|
@ -83,7 +83,6 @@ public:
|
||||
enum EVisitDest {VISIT_DEST, DONT_VISIT_DEST};
|
||||
enum ELEaveTile {LEAVING_TILE, REMAINING_ON_TILE};
|
||||
|
||||
CVCMIServer *s;
|
||||
std::map<PlayerColor, CConnection*> connections; //player color -> connection to client with interface of that player
|
||||
PlayerStatuses states; //player color -> player state
|
||||
std::set<CConnection*> conns;
|
||||
|
@ -239,8 +239,9 @@ CBattleQuery::CBattleQuery(const BattleInfo *Bi)
|
||||
}
|
||||
|
||||
CBattleQuery::CBattleQuery()
|
||||
:bi(nullptr)
|
||||
{
|
||||
|
||||
belligerents[0] = belligerents[1] = nullptr;
|
||||
}
|
||||
|
||||
bool CBattleQuery::blocksPack(const CPack *pack) const
|
||||
@ -323,7 +324,10 @@ void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &obj
|
||||
{
|
||||
// do not change to dynamic_ptr_cast - SIGSEGV!
|
||||
auto obj = dynamic_cast<const CGTeleport*>(objectVisit.visitedObject);
|
||||
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
||||
if(obj)
|
||||
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
||||
else
|
||||
logGlobal->error("Invalid instance in teleport query");
|
||||
}
|
||||
|
||||
CTeleportDialogQuery::CTeleportDialogQuery(const TeleportDialog &td)
|
||||
|
@ -177,16 +177,10 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
return gh->sendResources(val, player, static_cast<Res::ERes>(r1), PlayerColor(r2));
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
if(!hero)
|
||||
COMPLAIN_AND_RETURN("Only hero can sell creatures!");
|
||||
return gh->sellCreatures(val, m, hero, SlotID(r1), static_cast<Res::ERes>(r2));
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
if(!hero)
|
||||
COMPLAIN_AND_RETURN("Only hero can buy artifacts!");
|
||||
return gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1), ArtifactID(r2));
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
if(!hero)
|
||||
COMPLAIN_AND_RETURN("Only hero can sell artifacts!");
|
||||
return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast<Res::ERes>(r2));
|
||||
case EMarketMode::CREATURE_UNDEAD:
|
||||
return gh->transformInUndead(m, hero, SlotID(r1));
|
||||
|
Loading…
Reference in New Issue
Block a user