mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Merge branch 'develop-upstream' into town-buildings
# Conflicts: # client/CPlayerInterface.cpp # client/windows/CTradeWindow.cpp # config/objects/generic.json # lib/mapObjects/CGMarket.cpp # lib/mapObjects/CGMarket.h # lib/mapObjects/CGTownInstance.cpp # lib/mapObjects/CommonConstructors.cpp # lib/mapObjects/CommonConstructors.h
This commit is contained in:
commit
0250e6fb92
@ -56,10 +56,7 @@ struct EvaluationResult
|
||||
class BattleExchangeVariant
|
||||
{
|
||||
public:
|
||||
BattleExchangeVariant()
|
||||
:dpsScore(0), attackerValue()
|
||||
{
|
||||
}
|
||||
BattleExchangeVariant(): dpsScore(0) {}
|
||||
|
||||
int64_t trackAttack(const AttackPossibility & ap, HypotheticBattle & state);
|
||||
|
||||
@ -92,10 +89,7 @@ private:
|
||||
std::vector<battle::Units> turnOrder;
|
||||
|
||||
public:
|
||||
BattleExchangeEvaluator(std::shared_ptr<CBattleInfoCallback> cb, std::shared_ptr<Environment> env)
|
||||
:cb(cb), reachabilityMap(), env(env), turnOrder()
|
||||
{
|
||||
}
|
||||
BattleExchangeEvaluator(std::shared_ptr<CBattleInfoCallback> cb, std::shared_ptr<Environment> env): cb(cb), env(env) {}
|
||||
|
||||
EvaluationResult findBestTarget(const battle::Unit * activeStack, PotentialTargets & targets, HypotheticBattle & hb);
|
||||
int64_t calculateExchange(const AttackPossibility & ap, PotentialTargets & targets, HypotheticBattle & hb);
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
using namespace tbb;
|
||||
|
||||
typedef std::pair<ui32, std::vector<CreatureID>> dwellingContent;
|
||||
using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
|
||||
|
||||
namespace NKAI
|
||||
{
|
||||
@ -305,10 +305,10 @@ public:
|
||||
public:
|
||||
using ptr_type = std::unique_ptr<T, External_Deleter>;
|
||||
|
||||
SharedPool(std::function<std::unique_ptr<T>()> elementFactory)
|
||||
: elementFactory(elementFactory), pool(), sync(), instance_tracker(new SharedPool<T>*(this))
|
||||
SharedPool(std::function<std::unique_ptr<T>()> elementFactory):
|
||||
elementFactory(elementFactory), pool(), instance_tracker(new SharedPool<T> *(this))
|
||||
{}
|
||||
|
||||
|
||||
void add(std::unique_ptr<T> t)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(sync);
|
||||
|
@ -32,13 +32,8 @@ struct SlotInfo
|
||||
struct ArmyUpgradeInfo
|
||||
{
|
||||
std::vector<SlotInfo> resultingArmy;
|
||||
uint64_t upgradeValue;
|
||||
uint64_t upgradeValue = 0;
|
||||
TResources upgradeCost;
|
||||
|
||||
ArmyUpgradeInfo()
|
||||
: resultingArmy(), upgradeValue(0), upgradeCost()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT IArmyManager //: public: IAbstractManager
|
||||
|
@ -62,8 +62,11 @@ public:
|
||||
HeroRole townRole;
|
||||
bool hasSomethingToBuild;
|
||||
|
||||
TownDevelopmentInfo(const CGTownInstance* town)
|
||||
:town(town), armyStrength(0), toBuild(), townDevelopmentCost(), requiredResources(), townRole(HeroRole::SCOUT), hasSomethingToBuild(false)
|
||||
TownDevelopmentInfo(const CGTownInstance * town):
|
||||
town(town),
|
||||
armyStrength(0),
|
||||
townRole(HeroRole::SCOUT),
|
||||
hasSomethingToBuild(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct ClusterObjectInfo
|
||||
uint8_t turn;
|
||||
};
|
||||
|
||||
typedef tbb::concurrent_hash_map<const CGObjectInstance *, ClusterObjectInfo> ClusterObjects;
|
||||
using ClusterObjects = tbb::concurrent_hash_map<const CGObjectInstance *, ClusterObjectInfo>;
|
||||
|
||||
struct ObjectCluster
|
||||
{
|
||||
@ -36,11 +36,8 @@ public:
|
||||
}
|
||||
|
||||
void addObject(const CGObjectInstance * object, const AIPath & path, float priority);
|
||||
|
||||
ObjectCluster(const CGObjectInstance * blocker)
|
||||
:objects(), blocker(blocker)
|
||||
{
|
||||
}
|
||||
|
||||
ObjectCluster(const CGObjectInstance * blocker): blocker(blocker) {}
|
||||
|
||||
ObjectCluster() : ObjectCluster(nullptr)
|
||||
{
|
||||
@ -50,7 +47,7 @@ public:
|
||||
const CGObjectInstance * calculateCenter() const;
|
||||
};
|
||||
|
||||
typedef tbb::concurrent_hash_map<const CGObjectInstance *, std::shared_ptr<ObjectCluster>> ClusterMap;
|
||||
using ClusterMap = tbb::concurrent_hash_map<const CGObjectInstance *, std::shared_ptr<ObjectCluster>>;
|
||||
|
||||
class ObjectClusterizer
|
||||
{
|
||||
@ -67,10 +64,7 @@ public:
|
||||
std::vector<std::shared_ptr<ObjectCluster>> getLockedClusters() const;
|
||||
const CGObjectInstance * getBlocker(const AIPath & path) const;
|
||||
|
||||
ObjectClusterizer(const Nullkiller * ai)
|
||||
:nearObjects(), farObjects(), blockedObjects(), ai(ai)
|
||||
{
|
||||
}
|
||||
ObjectClusterizer(const Nullkiller * ai): ai(ai) {}
|
||||
|
||||
private:
|
||||
bool shouldVisitObject(const CGObjectInstance * obj) const;
|
||||
|
@ -22,7 +22,7 @@ struct GoalHash
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<Goals::TSubgoal, Goals::TGoalVec, GoalHash> TGoalHashSet;
|
||||
using TGoalHashSet = std::unordered_map<Goals::TSubgoal, Goals::TGoalVec, GoalHash>;
|
||||
|
||||
class DeepDecomposer
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ private:
|
||||
TacticalAdvantageEngine tacticalAdvantageEngine;
|
||||
|
||||
public:
|
||||
FuzzyHelper(const Nullkiller * ai) : ai(ai), tacticalAdvantageEngine() {}
|
||||
FuzzyHelper(const Nullkiller * ai): ai(ai) {}
|
||||
|
||||
ui64 estimateBankDanger(const CBank * bank); //TODO: move to another class?
|
||||
|
||||
|
@ -297,6 +297,12 @@ int RewardEvaluator::getGoldCost(const CGObjectInstance * target, const CGHeroIn
|
||||
{
|
||||
if(!target)
|
||||
return 0;
|
||||
|
||||
if(auto * m = dynamic_cast<const IMarket *>(target))
|
||||
{
|
||||
if(m->allowsTrade(EMarketMode::RESOURCE_SKILL))
|
||||
return 2000;
|
||||
}
|
||||
|
||||
switch(target->ID)
|
||||
{
|
||||
@ -305,8 +311,6 @@ int RewardEvaluator::getGoldCost(const CGObjectInstance * target, const CGHeroIn
|
||||
case Obj::SCHOOL_OF_MAGIC:
|
||||
case Obj::SCHOOL_OF_WAR:
|
||||
return 1000;
|
||||
case Obj::UNIVERSITY:
|
||||
return 2000;
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR2:
|
||||
case Obj::CREATURE_GENERATOR3:
|
||||
|
@ -81,9 +81,9 @@ namespace Goals
|
||||
bool operator<(const TSubgoal & rhs) const;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ITask> TTask;
|
||||
typedef std::vector<TTask> TTaskVec;
|
||||
typedef std::vector<TSubgoal> TGoalVec;
|
||||
using TTask = std::shared_ptr<ITask>;
|
||||
using TTaskVec = std::vector<TTask>;
|
||||
using TGoalVec = std::vector<TSubgoal>;
|
||||
|
||||
//method chaining + clone pattern
|
||||
#define SETTER(type, field) AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
|
||||
@ -107,8 +107,7 @@ namespace Goals
|
||||
const CGTownInstance *town; SETTER(CGTownInstance *, town)
|
||||
int bid; SETTER(int, bid)
|
||||
|
||||
AbstractGoal(EGoals goal = EGoals::INVALID)
|
||||
: goalType(goal), hero()
|
||||
AbstractGoal(EGoals goal = EGoals::INVALID): goalType(goal)
|
||||
{
|
||||
isAbstract = false;
|
||||
value = 0;
|
||||
|
@ -205,14 +205,14 @@ public:
|
||||
|
||||
inline void updateAINode(CGPathNode * node, std::function<void (AIPathNode *)> updater)
|
||||
{
|
||||
auto aiNode = static_cast<AIPathNode *>(node);
|
||||
auto * aiNode = static_cast<AIPathNode *>(node);
|
||||
|
||||
updater(aiNode);
|
||||
}
|
||||
|
||||
inline const CGHeroInstance * getHero(const CGPathNode * node) const
|
||||
{
|
||||
auto aiNode = getAINode(node);
|
||||
const auto * aiNode = getAINode(node);
|
||||
|
||||
return aiNode->actor->hero;
|
||||
}
|
||||
|
@ -32,9 +32,7 @@ public:
|
||||
virtual bool needsLastStack() const override;
|
||||
std::shared_ptr<SpecialAction> getActorAction() const;
|
||||
|
||||
HeroExchangeArmy() : CArmedInstance(true), armyCost(), requireBuyArmy(false)
|
||||
{
|
||||
}
|
||||
HeroExchangeArmy(): CArmedInstance(true), requireBuyArmy(false) {}
|
||||
};
|
||||
|
||||
struct ExchangeResult
|
||||
|
@ -23,9 +23,9 @@
|
||||
class CCallback;
|
||||
struct creInfo;
|
||||
|
||||
typedef const int3 & crint3;
|
||||
typedef const std::string & crstring;
|
||||
typedef std::pair<ui32, std::vector<CreatureID>> dwellingContent;
|
||||
using crint3 = const int3 &;
|
||||
using crstring = const std::string &;
|
||||
using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
|
||||
|
||||
const int GOLD_MINE_PRODUCTION = 1000, WOOD_ORE_MINE_PRODUCTION = 2, RESOURCE_MINE_PRODUCTION = 1;
|
||||
const int ACTUAL_RESOURCE_COUNT = 7;
|
||||
|
@ -76,7 +76,7 @@ namespace Goals
|
||||
//TODO: serialize?
|
||||
};
|
||||
|
||||
typedef std::vector<TSubgoal> TGoalVec;
|
||||
using TGoalVec = std::vector<TSubgoal>;
|
||||
|
||||
//method chaining + clone pattern
|
||||
#define VSETTER(type, field) virtual AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
|
||||
@ -121,8 +121,7 @@ namespace Goals
|
||||
TSubgoal parent; VSETTER(TSubgoal, parent)
|
||||
EvaluationContext evaluationContext; VSETTER(EvaluationContext, evaluationContext)
|
||||
|
||||
AbstractGoal(EGoals goal = EGoals::INVALID)
|
||||
: goalType(goal), evaluationContext()
|
||||
AbstractGoal(EGoals goal = EGoals::INVALID): goalType(goal)
|
||||
{
|
||||
priority = 0;
|
||||
isElementar = false;
|
||||
|
@ -131,13 +131,16 @@ TSubgoal CollectRes::whatToDoToTrade()
|
||||
|
||||
std::vector<const CGObjectInstance *> visObjs;
|
||||
ai->retrieveVisitableObjs(visObjs, true);
|
||||
for (const CGObjectInstance * obj : visObjs)
|
||||
for(const CGObjectInstance * obj : visObjs)
|
||||
{
|
||||
if (const IMarket * m = IMarket::castFrom(obj, false))
|
||||
if(const IMarket * m = IMarket::castFrom(obj, false); m->allowsTrade(EMarketMode::RESOURCE_RESOURCE))
|
||||
{
|
||||
if (obj->ID == Obj::TOWN && obj->tempOwner == ai->playerID && m->allowsTrade(EMarketMode::RESOURCE_RESOURCE))
|
||||
markets.push_back(m);
|
||||
else if (obj->ID == Obj::TRADING_POST)
|
||||
if(obj->ID == Obj::TOWN)
|
||||
{
|
||||
if(obj->tempOwner == ai->playerID)
|
||||
markets.push_back(m);
|
||||
}
|
||||
else
|
||||
markets.push_back(m);
|
||||
}
|
||||
}
|
||||
@ -171,7 +174,7 @@ TSubgoal CollectRes::whatToDoToTrade()
|
||||
const IMarket * m = markets.back();
|
||||
//attempt trade at back (best prices)
|
||||
int howManyCanWeBuy = 0;
|
||||
for (auto i = EGameResID::WOOD; i <= EGameResID::GOLD; vstd::advance(i, 1))
|
||||
for (GameResID i = EGameResID::WOOD; i <= EGameResID::GOLD; ++i)
|
||||
{
|
||||
if (GameResID(i) == resID)
|
||||
continue;
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
class CCallback;
|
||||
|
||||
extern boost::thread_specific_ptr<CCallback> cb; //for templates
|
||||
|
||||
struct AIPathNode : public CGPathNode
|
||||
{
|
||||
uint32_t chainMask;
|
||||
|
6
Global.h
6
Global.h
@ -543,10 +543,12 @@ namespace vstd
|
||||
});
|
||||
}
|
||||
|
||||
/// Increments value by specific delta
|
||||
/// similar to std::next but works with other types, e.g. enum class
|
||||
template<typename T>
|
||||
void advance(T &obj, int change)
|
||||
T next(const T &obj, int change)
|
||||
{
|
||||
obj = (T)(((int)obj) + change);
|
||||
return static_cast<T>(static_cast<ptrdiff_t>(obj) + change);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
|
@ -112,9 +112,8 @@
|
||||
"matchTerrainToTown" : false,
|
||||
"treasure" :
|
||||
[
|
||||
{ "min" : 0, "max" : 0, "density" : 1 },
|
||||
{ "min" : 0, "max" : 0, "density" : 1 },
|
||||
{ "min" : 0, "max" : 0, "density" : 1 }
|
||||
{ "min" : 100, "max" : 1000, "density" : 10 },
|
||||
{ "min" : 1000, "max" : 3000, "density" : 1 }
|
||||
]
|
||||
},
|
||||
"12" :
|
||||
|
@ -31,6 +31,7 @@ set(client_SRCS
|
||||
gui/CursorHandler.cpp
|
||||
gui/InterfaceObjectConfigurable.cpp
|
||||
gui/NotificationHandler.cpp
|
||||
gui/ShortcutHandler.cpp
|
||||
|
||||
lobby/CBonusSelection.cpp
|
||||
lobby/CCampaignInfoScreen.cpp
|
||||
@ -85,6 +86,12 @@ set(client_SRCS
|
||||
widgets/MiscWidgets.cpp
|
||||
widgets/ObjectLists.cpp
|
||||
widgets/TextControls.cpp
|
||||
widgets/CArtifactsOfHeroBase.cpp
|
||||
widgets/CArtifactsOfHeroMain.cpp
|
||||
widgets/CArtifactsOfHeroKingdom.cpp
|
||||
widgets/CArtifactsOfHeroAltar.cpp
|
||||
widgets/CArtifactsOfHeroMarket.cpp
|
||||
widgets/CWindowWithArtifacts.cpp
|
||||
|
||||
windows/CCastleInterface.cpp
|
||||
windows/CCreatureWindow.cpp
|
||||
@ -153,6 +160,8 @@ set(client_HEADERS
|
||||
gui/InterfaceObjectConfigurable.h
|
||||
gui/MouseButton.h
|
||||
gui/NotificationHandler.h
|
||||
gui/Shortcut.h
|
||||
gui/ShortcutHandler.h
|
||||
gui/TextAlignment.h
|
||||
|
||||
lobby/CBonusSelection.h
|
||||
@ -214,6 +223,12 @@ set(client_HEADERS
|
||||
widgets/MiscWidgets.h
|
||||
widgets/ObjectLists.h
|
||||
widgets/TextControls.h
|
||||
widgets/CArtifactsOfHeroBase.h
|
||||
widgets/CArtifactsOfHeroMain.h
|
||||
widgets/CArtifactsOfHeroKingdom.h
|
||||
widgets/CArtifactsOfHeroAltar.h
|
||||
widgets/CArtifactsOfHeroMarket.h
|
||||
widgets/CWindowWithArtifacts.h
|
||||
|
||||
windows/CCastleInterface.h
|
||||
windows/CCreatureWindow.h
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
struct _Mix_Music;
|
||||
struct SDL_RWops;
|
||||
typedef struct _Mix_Music Mix_Music;
|
||||
using Mix_Music = struct _Mix_Music;
|
||||
struct Mix_Chunk;
|
||||
|
||||
class CAudioBase {
|
||||
|
@ -1709,22 +1709,15 @@ void CPlayerInterface::stopMovement()
|
||||
void CPlayerInterface::showMarketWindow(const IMarket *market, const CGHeroInstance *visitor)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
auto * o = dynamic_cast<const CGObjectInstance *>(market);
|
||||
if(o && o->ID == Obj::ALTAR_OF_SACRIFICE)
|
||||
{
|
||||
//EEMarketMode mode = market->availableModes().front();
|
||||
if (market->allowsTrade(EMarketMode::ARTIFACT_EXP) && visitor->getAlignment() != EAlignment::EVIL)
|
||||
GH.pushIntT<CAltarWindow>(market, visitor, EMarketMode::ARTIFACT_EXP);
|
||||
else if (market->allowsTrade(EMarketMode::CREATURE_EXP) && visitor->getAlignment() != EAlignment::GOOD)
|
||||
GH.pushIntT<CAltarWindow>(market, visitor, EMarketMode::CREATURE_EXP);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(market->allowsTrade(EMarketMode::CREATURE_UNDEAD))
|
||||
GH.pushIntT<CTransformerWindow>(market, visitor);
|
||||
else
|
||||
GH.pushIntT<CMarketplaceWindow>(market, visitor, market->availableModes().front());
|
||||
}
|
||||
|
||||
if(market->allowsTrade(EMarketMode::ARTIFACT_EXP) && visitor->getAlignment() != EAlignment::EVIL)
|
||||
GH.pushIntT<CAltarWindow>(market, visitor, EMarketMode::ARTIFACT_EXP);
|
||||
else if(market->allowsTrade(EMarketMode::CREATURE_EXP) && visitor->getAlignment() != EAlignment::GOOD)
|
||||
GH.pushIntT<CAltarWindow>(market, visitor, EMarketMode::CREATURE_EXP);
|
||||
else if(market->allowsTrade(EMarketMode::CREATURE_UNDEAD))
|
||||
GH.pushIntT<CTransformerWindow>(market, visitor);
|
||||
else if(!market->availableModes().empty())
|
||||
GH.pushIntT<CMarketplaceWindow>(market, visitor, market->availableModes().front());
|
||||
}
|
||||
|
||||
void CPlayerInterface::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor)
|
||||
@ -1796,7 +1789,7 @@ void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al)
|
||||
al.slot.num);
|
||||
return;
|
||||
}
|
||||
CHeroArtPlace::askToAssemble(hero, al.slot);
|
||||
ArtifactUtilsClient::askToAssemble(hero, al.slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ namespace boost { class thread; }
|
||||
template<typename T>
|
||||
class ThreadSafeVector
|
||||
{
|
||||
typedef std::vector<T> TVector;
|
||||
typedef boost::unique_lock<boost::mutex> TLock;
|
||||
using TVector = std::vector<T>;
|
||||
using TLock = boost::unique_lock<boost::mutex>;
|
||||
TVector items;
|
||||
boost::mutex mx;
|
||||
boost::condition_variable cond;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../windows/settings/SettingsMainWindow.h"
|
||||
@ -95,7 +96,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
gems.push_back(std::make_shared<CAnimImage>(ADVOPT.gemG[g], 0, 0, ADVOPT.gemX[g], ADVOPT.gemY[g]));
|
||||
}
|
||||
|
||||
auto makeButton = [&](int textID, std::function<void()> callback, config::ButtonInfo info, int key) -> std::shared_ptr<CButton>
|
||||
auto makeButton = [&](int textID, std::function<void()> callback, config::ButtonInfo info, EShortcut key) -> std::shared_ptr<CButton>
|
||||
{
|
||||
auto button = std::make_shared<CButton>(Point(info.x, info.y), info.defName, CGI->generaltexth->zelp[textID], callback, key, info.playerColoured);
|
||||
for(auto image : info.additionalDefs)
|
||||
@ -103,16 +104,16 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
return button;
|
||||
};
|
||||
|
||||
kingOverview = makeButton(293, std::bind(&CAdventureMapInterface::fshowOverview,this), ADVOPT.kingOverview, SDLK_k);
|
||||
underground = makeButton(294, std::bind(&CAdventureMapInterface::fswitchLevel,this), ADVOPT.underground, SDLK_u);
|
||||
questlog = makeButton(295, std::bind(&CAdventureMapInterface::fshowQuestlog,this), ADVOPT.questlog, SDLK_q);
|
||||
sleepWake = makeButton(296, std::bind(&CAdventureMapInterface::fsleepWake,this), ADVOPT.sleepWake, SDLK_w);
|
||||
moveHero = makeButton(297, std::bind(&CAdventureMapInterface::fmoveHero,this), ADVOPT.moveHero, SDLK_m);
|
||||
spellbook = makeButton(298, std::bind(&CAdventureMapInterface::fshowSpellbok,this), ADVOPT.spellbook, SDLK_c);
|
||||
advOptions = makeButton(299, std::bind(&CAdventureMapInterface::fadventureOPtions,this), ADVOPT.advOptions, SDLK_a);
|
||||
sysOptions = makeButton(300, std::bind(&CAdventureMapInterface::fsystemOptions,this), ADVOPT.sysOptions, SDLK_o);
|
||||
nextHero = makeButton(301, std::bind(&CAdventureMapInterface::fnextHero,this), ADVOPT.nextHero, SDLK_h);
|
||||
endTurn = makeButton(302, std::bind(&CAdventureMapInterface::fendTurn,this), ADVOPT.endTurn, SDLK_e);
|
||||
kingOverview = makeButton(293, std::bind(&CAdventureMapInterface::fshowOverview,this), ADVOPT.kingOverview, EShortcut::ADVENTURE_KINGDOM_OVERVIEW);
|
||||
underground = makeButton(294, std::bind(&CAdventureMapInterface::fswitchLevel,this), ADVOPT.underground, EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL);
|
||||
questlog = makeButton(295, std::bind(&CAdventureMapInterface::fshowQuestlog,this), ADVOPT.questlog, EShortcut::ADVENTURE_QUEST_LOG);
|
||||
sleepWake = makeButton(296, std::bind(&CAdventureMapInterface::fsleepWake,this), ADVOPT.sleepWake, EShortcut::ADVENTURE_TOGGLE_SLEEP);
|
||||
moveHero = makeButton(297, std::bind(&CAdventureMapInterface::fmoveHero,this), ADVOPT.moveHero, EShortcut::ADVENTURE_MOVE_HERO);
|
||||
spellbook = makeButton(298, std::bind(&CAdventureMapInterface::fshowSpellbok,this), ADVOPT.spellbook, EShortcut::ADVENTURE_CAST_SPELL);
|
||||
advOptions = makeButton(299, std::bind(&CAdventureMapInterface::fadventureOPtions,this), ADVOPT.advOptions, EShortcut::ADVENTURE_GAME_OPTIONS);
|
||||
sysOptions = makeButton(300, std::bind(&CAdventureMapInterface::fsystemOptions,this), ADVOPT.sysOptions, EShortcut::GLOBAL_OPTIONS);
|
||||
nextHero = makeButton(301, std::bind(&CAdventureMapInterface::fnextHero,this), ADVOPT.nextHero, EShortcut::ADVENTURE_NEXT_HERO);
|
||||
endTurn = makeButton(302, std::bind(&CAdventureMapInterface::fendTurn,this), ADVOPT.endTurn, EShortcut::ADVENTURE_END_TURN);
|
||||
|
||||
int panelSpaceBottom = GH.screenDimensions().y - resdatabar->pos.h - 4;
|
||||
|
||||
@ -139,7 +140,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
worldViewBackConfig.y = 343 + 195;
|
||||
worldViewBackConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel(
|
||||
makeButton(288, std::bind(&CAdventureMapInterface::fworldViewBack,this), worldViewBackConfig, SDLK_ESCAPE), ACTIVATE | DEACTIVATE);
|
||||
makeButton(288, std::bind(&CAdventureMapInterface::fworldViewBack,this), worldViewBackConfig, EShortcut::GLOBAL_CANCEL), ACTIVATE | DEACTIVATE);
|
||||
|
||||
config::ButtonInfo worldViewPuzzleConfig = config::ButtonInfo();
|
||||
worldViewPuzzleConfig.defName = "VWPUZ.DEF";
|
||||
@ -148,7 +149,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
worldViewPuzzleConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // no help text for this one
|
||||
std::make_shared<CButton>(Point(worldViewPuzzleConfig.x, worldViewPuzzleConfig.y), worldViewPuzzleConfig.defName, std::pair<std::string, std::string>(),
|
||||
std::bind(&CPlayerInterface::showPuzzleMap,LOCPLINT), SDLK_p, worldViewPuzzleConfig.playerColoured), ACTIVATE | DEACTIVATE);
|
||||
std::bind(&CPlayerInterface::showPuzzleMap,LOCPLINT), EShortcut::ADVENTURE_VIEW_PUZZLE, worldViewPuzzleConfig.playerColoured), ACTIVATE | DEACTIVATE);
|
||||
|
||||
config::ButtonInfo worldViewScale1xConfig = config::ButtonInfo();
|
||||
worldViewScale1xConfig.defName = "VWMAG1.DEF";
|
||||
@ -156,7 +157,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
worldViewScale1xConfig.y = 23 + 195;
|
||||
worldViewScale1xConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // help text is wrong for this button
|
||||
makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale1x,this), worldViewScale1xConfig, SDLK_1), ACTIVATE | DEACTIVATE);
|
||||
makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale1x,this), worldViewScale1xConfig, EShortcut::SELECT_INDEX_1), ACTIVATE | DEACTIVATE);
|
||||
|
||||
config::ButtonInfo worldViewScale2xConfig = config::ButtonInfo();
|
||||
worldViewScale2xConfig.defName = "VWMAG2.DEF";
|
||||
@ -164,7 +165,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
worldViewScale2xConfig.y = 23 + 195;
|
||||
worldViewScale2xConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // help text is wrong for this button
|
||||
makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale2x,this), worldViewScale2xConfig, SDLK_2), ACTIVATE | DEACTIVATE);
|
||||
makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale2x,this), worldViewScale2xConfig, EShortcut::SELECT_INDEX_2), ACTIVATE | DEACTIVATE);
|
||||
|
||||
config::ButtonInfo worldViewScale4xConfig = config::ButtonInfo();
|
||||
worldViewScale4xConfig.defName = "VWMAG4.DEF";
|
||||
@ -172,7 +173,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
worldViewScale4xConfig.y = 23 + 195;
|
||||
worldViewScale4xConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // help text is wrong for this button
|
||||
makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale4x,this), worldViewScale4xConfig, SDLK_4), ACTIVATE | DEACTIVATE);
|
||||
makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale4x,this), worldViewScale4xConfig, EShortcut::SELECT_INDEX_4), ACTIVATE | DEACTIVATE);
|
||||
|
||||
config::ButtonInfo worldViewUndergroundConfig = config::ButtonInfo();
|
||||
worldViewUndergroundConfig.defName = "IAM010.DEF";
|
||||
@ -180,7 +181,7 @@ CAdventureMapInterface::CAdventureMapInterface():
|
||||
worldViewUndergroundConfig.x = GH.screenDimensions().x - 115;
|
||||
worldViewUndergroundConfig.y = 343 + 195;
|
||||
worldViewUndergroundConfig.playerColoured = true;
|
||||
worldViewUnderground = makeButton(294, std::bind(&CAdventureMapInterface::fswitchLevel,this), worldViewUndergroundConfig, SDLK_u);
|
||||
worldViewUnderground = makeButton(294, std::bind(&CAdventureMapInterface::fswitchLevel,this), worldViewUndergroundConfig, EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL);
|
||||
panelWorldView->addChildColorableButton(worldViewUnderground);
|
||||
|
||||
onCurrentPlayerChanged(LOCPLINT->playerID);
|
||||
@ -392,7 +393,6 @@ void CAdventureMapInterface::updateButtons()
|
||||
{
|
||||
bool state = LOCPLINT->localState->isHeroSleeping(hero);
|
||||
sleepWake->setIndex(state ? 1 : 0, true);
|
||||
sleepWake->assignedKeys = {state ? SDLK_w : SDLK_z};
|
||||
sleepWake->redraw();
|
||||
}
|
||||
}
|
||||
@ -607,17 +607,20 @@ void CAdventureMapInterface::centerOnObject(const CGObjectInstance * obj)
|
||||
terrain->onCenteredObject(obj);
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
void CAdventureMapInterface::keyPressed(EShortcut key)
|
||||
{
|
||||
if (state != EGameState::MAKING_TURN)
|
||||
return;
|
||||
|
||||
//fake mouse use to trigger onTileHovered()
|
||||
GH.fakeMouseMove();
|
||||
|
||||
const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero(); //selected hero
|
||||
const CGTownInstance *t = LOCPLINT->localState->getCurrentTown(); //selected town
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_g:
|
||||
case EShortcut::ADVENTURE_THIEVES_GUILD:
|
||||
if(GH.topInt()->type & BLOCK_ADV_HOTKEYS)
|
||||
return;
|
||||
|
||||
@ -634,40 +637,40 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithTavern"));
|
||||
}
|
||||
return;
|
||||
case SDLK_i:
|
||||
case EShortcut::ADVENTURE_VIEW_SCENARIO:
|
||||
if(isActive())
|
||||
CAdventureOptions::showScenarioInfo();
|
||||
return;
|
||||
case SDLK_s:
|
||||
case EShortcut::GAME_SAVE_GAME:
|
||||
if(isActive())
|
||||
GH.pushIntT<CSavingScreen>();
|
||||
return;
|
||||
case SDLK_l:
|
||||
case EShortcut::GAME_LOAD_GAME:
|
||||
if(isActive())
|
||||
LOCPLINT->proposeLoadingGame();
|
||||
return;
|
||||
case SDLK_d:
|
||||
case EShortcut::ADVENTURE_DIG_GRAIL:
|
||||
{
|
||||
if(h && isActive() && LOCPLINT->makingTurn)
|
||||
LOCPLINT->tryDiggging(h);
|
||||
return;
|
||||
}
|
||||
case SDLK_p:
|
||||
case EShortcut::ADVENTURE_VIEW_PUZZLE:
|
||||
if(isActive())
|
||||
LOCPLINT->showPuzzleMap();
|
||||
return;
|
||||
case SDLK_v:
|
||||
case EShortcut::ADVENTURE_VIEW_WORLD:
|
||||
if(isActive())
|
||||
LOCPLINT->viewWorldMap();
|
||||
return;
|
||||
case SDLK_r:
|
||||
case EShortcut::GAME_RESTART_GAME:
|
||||
if(isActive() && GH.isKeyboardCtrlDown())
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
|
||||
[](){ GH.pushUserEvent(EUserEvent::RESTART_GAME); }, nullptr);
|
||||
}
|
||||
return;
|
||||
case SDLK_SPACE: //space - try to revisit current object with selected hero
|
||||
case EShortcut::ADVENTURE_VISIT_OBJECT: //space - try to revisit current object with selected hero
|
||||
{
|
||||
if(!isActive())
|
||||
return;
|
||||
@ -677,7 +680,7 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
}
|
||||
}
|
||||
return;
|
||||
case SDLK_RETURN:
|
||||
case EShortcut::ADVENTURE_VIEW_SELECTED:
|
||||
{
|
||||
if(!isActive() || !LOCPLINT->localState->getCurrentArmy())
|
||||
return;
|
||||
@ -687,7 +690,7 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
LOCPLINT->openTownWindow(t);
|
||||
return;
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
case EShortcut::GLOBAL_CANCEL:
|
||||
{
|
||||
//FIXME: this case is never executed since AdvMapInt is disabled while in spellcasting mode
|
||||
if(!isActive() || GH.topInt().get() != this || !spellBeingCasted)
|
||||
@ -696,7 +699,7 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
abortCastingMode();
|
||||
return;
|
||||
}
|
||||
case SDLK_t:
|
||||
case EShortcut::GAME_OPEN_MARKETPLACE:
|
||||
{
|
||||
//act on key down if marketplace windows is not already opened
|
||||
if(GH.topInt()->type & BLOCK_ADV_HOTKEYS)
|
||||
@ -720,77 +723,55 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
else //if not - complain
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithMarket"));
|
||||
}
|
||||
else if(isActive()) //no ctrl, advmapint is on the top => switch to town
|
||||
case EShortcut::ADVENTURE_NEXT_TOWN:
|
||||
if(isActive() && !GH.isKeyboardCtrlDown()) //no ctrl, advmapint is on the top => switch to town
|
||||
{
|
||||
townList->selectNext();
|
||||
}
|
||||
return;
|
||||
}
|
||||
case SDLK_LALT:
|
||||
case SDLK_RALT:
|
||||
{
|
||||
//fake mouse use to trigger onTileHovered()
|
||||
GH.fakeMouseMove();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
auto direction = keyToMoveDirection(key);
|
||||
|
||||
if (!direction)
|
||||
return;
|
||||
|
||||
if(!h || !isActive())
|
||||
return;
|
||||
|
||||
if (CGI->mh->hasOngoingAnimations())
|
||||
return;
|
||||
|
||||
if(*direction == Point(0,0))
|
||||
{
|
||||
centerOnObject(h);
|
||||
return;
|
||||
}
|
||||
|
||||
int3 dst = h->visitablePos() + int3(direction->x, direction->y, 0);
|
||||
|
||||
if (!CGI->mh->isInMap((dst)))
|
||||
return;
|
||||
|
||||
if ( !LOCPLINT->localState->setPath(h, dst))
|
||||
return;
|
||||
|
||||
const CGPath & path = LOCPLINT->localState->getPath(h);
|
||||
|
||||
if (path.nodes.size() > 2)
|
||||
onHeroChanged(h);
|
||||
else
|
||||
if(!path.nodes[0].turns)
|
||||
LOCPLINT->moveHero(h, path);
|
||||
}
|
||||
return;
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_SW: return hotkeyMoveHeroDirectional({-1, +1});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_SS: return hotkeyMoveHeroDirectional({ 0, +1});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_SE: return hotkeyMoveHeroDirectional({+1, +1});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_WW: return hotkeyMoveHeroDirectional({-1, 0});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_EE: return hotkeyMoveHeroDirectional({+1, 0});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_NW: return hotkeyMoveHeroDirectional({-1, -1});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_NN: return hotkeyMoveHeroDirectional({ 0, -1});
|
||||
case EShortcut::ADVENTURE_MOVE_HERO_NE: return hotkeyMoveHeroDirectional({+1, -1});
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Point> CAdventureMapInterface::keyToMoveDirection(const SDL_Keycode & key)
|
||||
void CAdventureMapInterface::hotkeyMoveHeroDirectional(Point direction)
|
||||
{
|
||||
switch (key) {
|
||||
case SDLK_DOWN: return Point( 0, +1);
|
||||
case SDLK_LEFT: return Point(-1, 0);
|
||||
case SDLK_RIGHT: return Point(+1, 0);
|
||||
case SDLK_UP: return Point( 0, -1);
|
||||
const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero(); //selected hero
|
||||
|
||||
case SDLK_KP_1: return Point(-1, +1);
|
||||
case SDLK_KP_2: return Point( 0, +1);
|
||||
case SDLK_KP_3: return Point(+1, +1);
|
||||
case SDLK_KP_4: return Point(-1, 0);
|
||||
case SDLK_KP_5: return Point( 0, 0);
|
||||
case SDLK_KP_6: return Point(+1, 0);
|
||||
case SDLK_KP_7: return Point(-1, -1);
|
||||
case SDLK_KP_8: return Point( 0, -1);
|
||||
case SDLK_KP_9: return Point(+1, -1);
|
||||
if(!h || !isActive())
|
||||
return;
|
||||
|
||||
if (CGI->mh->hasOngoingAnimations())
|
||||
return;
|
||||
|
||||
if(direction == Point(0,0))
|
||||
{
|
||||
centerOnObject(h);
|
||||
return;
|
||||
}
|
||||
return std::nullopt;
|
||||
|
||||
int3 dst = h->visitablePos() + int3(direction.x, direction.y, 0);
|
||||
|
||||
if (!CGI->mh->isInMap((dst)))
|
||||
return;
|
||||
|
||||
if ( !LOCPLINT->localState->setPath(h, dst))
|
||||
return;
|
||||
|
||||
const CGPath & path = LOCPLINT->localState->getPath(h);
|
||||
|
||||
if (path.nodes.size() > 2)
|
||||
onHeroChanged(h);
|
||||
else
|
||||
if(!path.nodes[0].turns)
|
||||
LOCPLINT->moveHero(h, path);
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
|
||||
|
@ -116,6 +116,8 @@ private:
|
||||
void fnextHero();
|
||||
void fendTurn();
|
||||
|
||||
void hotkeyMoveHeroDirectional(Point direction);
|
||||
|
||||
bool isActive();
|
||||
void adjustActiveness(bool aiTurnStart); //should be called every time at AI/human turn transition; blocks GUI during AI turn
|
||||
|
||||
@ -130,7 +132,7 @@ private:
|
||||
|
||||
const CGObjectInstance *getActiveObject(const int3 &tile);
|
||||
|
||||
std::optional<Point> keyToMoveDirection(const SDL_Keycode & key);
|
||||
std::optional<Point> keyToMoveDirection(EShortcut key);
|
||||
|
||||
void endingTurn();
|
||||
|
||||
@ -149,7 +151,7 @@ protected:
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
|
||||
public:
|
||||
CAdventureMapInterface();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../lobby/CCampaignInfoScreen.h"
|
||||
#include "../lobby/CScenarioInfoScreen.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -27,19 +28,18 @@ CAdventureOptions::CAdventureOptions()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
viewWorld = std::make_shared<CButton>(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_v);
|
||||
viewWorld = std::make_shared<CButton>(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_WORLD);
|
||||
viewWorld->addCallback( [] { LOCPLINT->viewWorldMap(); });
|
||||
|
||||
exit = std::make_shared<CButton>(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&CAdventureOptions::close, this), SDLK_RETURN);
|
||||
exit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&CAdventureOptions::close, this), EShortcut::GLOBAL_RETURN);
|
||||
|
||||
scenInfo = std::make_shared<CButton>(Point(24, 198), "ADVINFO.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_i);
|
||||
scenInfo = std::make_shared<CButton>(Point(24, 198), "ADVINFO.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_SCENARIO);
|
||||
scenInfo->addCallback(CAdventureOptions::showScenarioInfo);
|
||||
|
||||
puzzle = std::make_shared<CButton>(Point(24, 81), "ADVPUZ.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_p);
|
||||
puzzle = std::make_shared<CButton>(Point(24, 81), "ADVPUZ.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_PUZZLE);
|
||||
puzzle->addCallback(std::bind(&CPlayerInterface::showPuzzleMap, LOCPLINT));
|
||||
|
||||
dig = std::make_shared<CButton>(Point(24, 139), "ADVDIG.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_d);
|
||||
dig = std::make_shared<CButton>(Point(24, 139), "ADVDIG.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_DIG_GRAIL);
|
||||
if(const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero())
|
||||
dig->addCallback(std::bind(&CPlayerInterface::tryDiggging, LOCPLINT, h));
|
||||
else
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../ClientCommandManager.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../render/Colors.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -108,30 +109,29 @@ void CInGameConsole::print(const std::string & txt)
|
||||
GH.totalRedraw(); // FIXME: ingame console has no parent widget set
|
||||
}
|
||||
|
||||
void CInGameConsole::keyPressed (const SDL_Keycode & key)
|
||||
void CInGameConsole::keyPressed (EShortcut key)
|
||||
{
|
||||
if (LOCPLINT->cingconsole != this)
|
||||
return;
|
||||
|
||||
if(!captureAllKeys && key != SDLK_TAB)
|
||||
if(!captureAllKeys && key != EShortcut::GAME_ACTIVATE_CONSOLE)
|
||||
return; //because user is not entering any text
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_TAB:
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
if(captureAllKeys)
|
||||
{
|
||||
endEnteringText(false);
|
||||
}
|
||||
else if(SDLK_TAB == key)
|
||||
{
|
||||
startEnteringText();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN: //enter key
|
||||
case EShortcut::GLOBAL_CANCEL:
|
||||
if(captureAllKeys)
|
||||
endEnteringText(false);
|
||||
break;
|
||||
|
||||
case EShortcut::GAME_ACTIVATE_CONSOLE:
|
||||
if(captureAllKeys)
|
||||
endEnteringText(false);
|
||||
else
|
||||
startEnteringText();
|
||||
break;
|
||||
|
||||
case EShortcut::GLOBAL_ACCEPT:
|
||||
{
|
||||
if(!enteredText.empty() && captureAllKeys)
|
||||
{
|
||||
@ -145,7 +145,7 @@ void CInGameConsole::keyPressed (const SDL_Keycode & key)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_BACKSPACE:
|
||||
case EShortcut::GLOBAL_BACKSPACE:
|
||||
{
|
||||
if(enteredText.size() > 1)
|
||||
{
|
||||
@ -155,7 +155,7 @@ void CInGameConsole::keyPressed (const SDL_Keycode & key)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_UP: //up arrow
|
||||
case EShortcut::MOVE_UP:
|
||||
{
|
||||
if(previouslyEntered.empty())
|
||||
break;
|
||||
@ -174,7 +174,7 @@ void CInGameConsole::keyPressed (const SDL_Keycode & key)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN: //down arrow
|
||||
case EShortcut::MOVE_DOWN:
|
||||
{
|
||||
if(prevEntDisp != -1 && prevEntDisp+1 < previouslyEntered.size())
|
||||
{
|
||||
@ -190,10 +190,6 @@ void CInGameConsole::keyPressed (const SDL_Keycode & key)
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
void tick(uint32_t msPassed) override;
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
void textInputed(const std::string & enteredText) override;
|
||||
void textEdited(const std::string & enteredText) override;
|
||||
|
||||
|
@ -80,7 +80,7 @@ std::string CResDataBar::buildDateString()
|
||||
void CResDataBar::draw(SDL_Surface * to)
|
||||
{
|
||||
//TODO: all this should be labels, but they require proper text update on change
|
||||
for (auto i=GameResID(EGameResID::WOOD); i <= GameResID(EGameResID::GOLD); vstd::advance(i, 1))
|
||||
for (GameResID i=EGameResID::WOOD; i <= GameResID(EGameResID::GOLD); ++i)
|
||||
{
|
||||
std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(i));
|
||||
|
||||
|
@ -243,7 +243,7 @@ std::set<BattleHex> BattleFieldController::getMovementRangeForHoveredStack()
|
||||
if (!owner.stacksController->getActiveStack())
|
||||
return result;
|
||||
|
||||
if (!settings["battle"]["movementHighlightOnHover"].Bool())
|
||||
if (!settings["battle"]["movementHighlightOnHover"].Bool() && !GH.isKeyboardShiftDown())
|
||||
return result;
|
||||
|
||||
auto hoveredHex = getHoveredHex();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "../CVideoHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
@ -406,12 +407,12 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
||||
background->colorize(owner.playerID);
|
||||
pos = center(background->pos);
|
||||
|
||||
exit = std::make_shared<CButton>(Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, SDLK_RETURN);
|
||||
exit = std::make_shared<CButton>(Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, EShortcut::GLOBAL_ACCEPT);
|
||||
exit->setBorderColor(Colors::METALLIC_GOLD);
|
||||
|
||||
if(allowReplay)
|
||||
{
|
||||
repeat = std::make_shared<CButton>(Point(24, 505), "icn6432.def", std::make_pair("", ""), [&](){ bRepeatf();}, SDLK_ESCAPE);
|
||||
repeat = std::make_shared<CButton>(Point(24, 505), "icn6432.def", std::make_pair("", ""), [&](){ bRepeatf();}, EShortcut::GLOBAL_CANCEL);
|
||||
repeat->setBorderColor(Colors::METALLIC_GOLD);
|
||||
labels.push_back(std::make_shared<CLabel>(232, 520, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.battleResultsWindow.applyResultsLabel")));
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../windows/CSpellWindow.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/Images.h"
|
||||
@ -50,19 +51,23 @@ BattleWindow::BattleWindow(BattleInterface & owner):
|
||||
|
||||
const JsonNode config(ResourceID("config/widgets/BattleWindow.json"));
|
||||
|
||||
addCallback("options", std::bind(&BattleWindow::bOptionsf, this));
|
||||
addCallback("surrender", std::bind(&BattleWindow::bSurrenderf, this));
|
||||
addCallback("flee", std::bind(&BattleWindow::bFleef, this));
|
||||
addCallback("autofight", std::bind(&BattleWindow::bAutofightf, this));
|
||||
addCallback("spellbook", std::bind(&BattleWindow::bSpellf, this));
|
||||
addCallback("wait", std::bind(&BattleWindow::bWaitf, this));
|
||||
addCallback("defence", std::bind(&BattleWindow::bDefencef, this));
|
||||
addCallback("consoleUp", std::bind(&BattleWindow::bConsoleUpf, this));
|
||||
addCallback("consoleDown", std::bind(&BattleWindow::bConsoleDownf, this));
|
||||
addCallback("tacticNext", std::bind(&BattleWindow::bTacticNextStack, this));
|
||||
addCallback("tacticEnd", std::bind(&BattleWindow::bTacticPhaseEnd, this));
|
||||
addCallback("alternativeAction", std::bind(&BattleWindow::bSwitchActionf, this));
|
||||
|
||||
addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this));
|
||||
addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this));
|
||||
addShortcut(EShortcut::BATTLE_RETREAT, std::bind(&BattleWindow::bFleef, this));
|
||||
addShortcut(EShortcut::BATTLE_AUTOCOMBAT, std::bind(&BattleWindow::bAutofightf, this));
|
||||
addShortcut(EShortcut::BATTLE_CAST_SPELL, std::bind(&BattleWindow::bSpellf, this));
|
||||
addShortcut(EShortcut::BATTLE_WAIT, std::bind(&BattleWindow::bWaitf, this));
|
||||
addShortcut(EShortcut::BATTLE_DEFEND, std::bind(&BattleWindow::bDefencef, this));
|
||||
addShortcut(EShortcut::BATTLE_CONSOLE_UP, std::bind(&BattleWindow::bConsoleUpf, this));
|
||||
addShortcut(EShortcut::BATTLE_CONSOLE_DOWN, std::bind(&BattleWindow::bConsoleDownf, this));
|
||||
addShortcut(EShortcut::BATTLE_TACTICS_NEXT, std::bind(&BattleWindow::bTacticNextStack, this));
|
||||
addShortcut(EShortcut::BATTLE_TACTICS_END, std::bind(&BattleWindow::bTacticPhaseEnd, this));
|
||||
addShortcut(EShortcut::BATTLE_SELECT_ACTION, std::bind(&BattleWindow::bSwitchActionf, this));
|
||||
|
||||
addShortcut(EShortcut::BATTLE_TOGGLE_QUEUE, [this](){ this->toggleQueueVisibility();});
|
||||
addShortcut(EShortcut::BATTLE_USE_CREATURE_SPELL, [this](){ this->owner.actionsController->enterCreatureCastingMode(); });
|
||||
addShortcut(EShortcut::GLOBAL_CANCEL, [this](){ this->owner.actionsController->endCastingSpell(); });
|
||||
|
||||
build(config);
|
||||
|
||||
console = widget<BattleConsole>("console");
|
||||
@ -182,43 +187,14 @@ void BattleWindow::deactivate()
|
||||
LOCPLINT->cingconsole->deactivate();
|
||||
}
|
||||
|
||||
void BattleWindow::keyPressed(const SDL_Keycode & key)
|
||||
void BattleWindow::keyPressed(EShortcut key)
|
||||
{
|
||||
if (owner.openingPlaying())
|
||||
{
|
||||
owner.openingEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
if(key == SDLK_q)
|
||||
{
|
||||
toggleQueueVisibility();
|
||||
}
|
||||
else if(key == SDLK_f)
|
||||
{
|
||||
owner.actionsController->enterCreatureCastingMode();
|
||||
}
|
||||
else if(key == SDLK_ESCAPE)
|
||||
{
|
||||
owner.actionsController->endCastingSpell();
|
||||
}
|
||||
else if(GH.isKeyboardShiftDown())
|
||||
{
|
||||
// save and activate setting
|
||||
Settings movementHighlightOnHover = settings.write["battle"]["movementHighlightOnHover"];
|
||||
movementHighlightOnHoverCache = movementHighlightOnHover->Bool();
|
||||
movementHighlightOnHover->Bool() = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleWindow::keyReleased(const SDL_Keycode & key)
|
||||
{
|
||||
if(!GH.isKeyboardShiftDown())
|
||||
{
|
||||
// set back to initial state
|
||||
Settings movementHighlightOnHover = settings.write["battle"]["movementHighlightOnHover"];
|
||||
movementHighlightOnHover->Bool() = movementHighlightOnHoverCache;
|
||||
}
|
||||
InterfaceObjectConfigurable::keyPressed(key);
|
||||
}
|
||||
|
||||
void BattleWindow::clickRight(tribool down, bool previousState)
|
||||
@ -554,40 +530,18 @@ void BattleWindow::blockUI(bool on)
|
||||
|
||||
bool canWait = owner.stacksController->getActiveStack() ? !owner.stacksController->getActiveStack()->waitedThisTurn : false;
|
||||
|
||||
if(auto w = widget<CButton>("options"))
|
||||
w->block(on);
|
||||
if(auto w = widget<CButton>("flee"))
|
||||
w->block(on || !owner.curInt->cb->battleCanFlee());
|
||||
if(auto w = widget<CButton>("surrender"))
|
||||
w->block(on || owner.curInt->cb->battleGetSurrenderCost() < 0);
|
||||
if(auto w = widget<CButton>("cast"))
|
||||
w->block(on || owner.tacticsMode || !canCastSpells);
|
||||
if(auto w = widget<CButton>("wait"))
|
||||
w->block(on || owner.tacticsMode || !canWait);
|
||||
if(auto w = widget<CButton>("defence"))
|
||||
w->block(on || owner.tacticsMode);
|
||||
if(auto w = widget<CButton>("alternativeAction"))
|
||||
w->block(on || owner.tacticsMode);
|
||||
if(auto w = widget<CButton>("autofight"))
|
||||
w->block(owner.actionsController->spellcastingModeActive());
|
||||
|
||||
auto btactEnd = widget<CButton>("tacticEnd");
|
||||
auto btactNext = widget<CButton>("tacticNext");
|
||||
if(owner.tacticsMode && btactEnd && btactNext)
|
||||
{
|
||||
btactNext->block(on);
|
||||
btactEnd->block(on);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto bConsoleUp = widget<CButton>("consoleUp");
|
||||
auto bConsoleDown = widget<CButton>("consoleDown");
|
||||
if(bConsoleUp && bConsoleDown)
|
||||
{
|
||||
bConsoleUp->block(on);
|
||||
bConsoleDown->block(on);
|
||||
}
|
||||
}
|
||||
setShortcutBlocked(EShortcut::GLOBAL_OPTIONS, on);
|
||||
setShortcutBlocked(EShortcut::BATTLE_RETREAT, on || !owner.curInt->cb->battleCanFlee());
|
||||
setShortcutBlocked(EShortcut::BATTLE_SURRENDER, on || owner.curInt->cb->battleGetSurrenderCost() < 0);
|
||||
setShortcutBlocked(EShortcut::BATTLE_CAST_SPELL, on || owner.tacticsMode || !canCastSpells);
|
||||
setShortcutBlocked(EShortcut::BATTLE_WAIT, on || owner.tacticsMode || !canWait);
|
||||
setShortcutBlocked(EShortcut::BATTLE_DEFEND, on || owner.tacticsMode);
|
||||
setShortcutBlocked(EShortcut::BATTLE_SELECT_ACTION, on || owner.tacticsMode);
|
||||
setShortcutBlocked(EShortcut::BATTLE_AUTOCOMBAT, owner.actionsController->spellcastingModeActive());
|
||||
setShortcutBlocked(EShortcut::BATTLE_TACTICS_END, on && owner.tacticsMode);
|
||||
setShortcutBlocked(EShortcut::BATTLE_TACTICS_NEXT, on && owner.tacticsMode);
|
||||
setShortcutBlocked(EShortcut::BATTLE_CONSOLE_DOWN, on && !owner.tacticsMode);
|
||||
setShortcutBlocked(EShortcut::BATTLE_CONSOLE_UP, on && !owner.tacticsMode);
|
||||
}
|
||||
|
||||
std::optional<uint32_t> BattleWindow::getQueueHoveredUnitId()
|
||||
|
@ -84,8 +84,7 @@ public:
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyReleased(const SDL_Keycode& key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
void show(SDL_Surface *to) override;
|
||||
void showAll(SDL_Surface *to) override;
|
||||
@ -98,9 +97,5 @@ public:
|
||||
|
||||
/// Set possible alternative options. If more than 1 - the last will be considered as default option
|
||||
void setAlternativeActions(const std::list<PossiblePlayerBattleAction> &);
|
||||
|
||||
private:
|
||||
/// used to save the state of this setting on toggle.
|
||||
bool movementHighlightOnHoverCache;
|
||||
};
|
||||
|
||||
|
@ -68,7 +68,7 @@ namespace AnimationControls
|
||||
class CreatureAnimation : public CIntObject
|
||||
{
|
||||
public:
|
||||
typedef std::function<float(CreatureAnimation *, ECreatureAnimType)> TSpeedController;
|
||||
using TSpeedController = std::function<float(CreatureAnimation *, ECreatureAnimType)>;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "CIntObject.h"
|
||||
#include "CursorHandler.h"
|
||||
#include "ShortcutHandler.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../render/Colors.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_timer.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_keycode.h>
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
#include <dispatch/dispatch.h>
|
||||
@ -93,6 +95,7 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
|
||||
|
||||
void CGuiHandler::init()
|
||||
{
|
||||
shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
|
||||
mainFPSmng = new CFramerateManager();
|
||||
mainFPSmng->init(settings["video"]["targetfps"].Integer());
|
||||
isPointerRelativeMode = settings["general"]["userRelativePointer"].Bool();
|
||||
@ -356,6 +359,10 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
if(current.type == SDL_KEYDOWN || current.type == SDL_KEYUP)
|
||||
{
|
||||
SDL_KeyboardEvent key = current.key;
|
||||
|
||||
if (key.repeat != 0)
|
||||
return; // ignore periodic event resends
|
||||
|
||||
if(current.type == SDL_KEYDOWN && key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool())
|
||||
{
|
||||
//TODO: we need some central place for all interface-independent hotkeys
|
||||
@ -397,32 +404,35 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
return;
|
||||
}
|
||||
|
||||
//translate numpad keys
|
||||
if(key.keysym.sym == SDLK_KP_ENTER)
|
||||
{
|
||||
key.keysym.sym = SDLK_RETURN;
|
||||
key.keysym.scancode = SDL_SCANCODE_RETURN;
|
||||
}
|
||||
auto shortcutsVector = shortcutsHandler().translateKeycode(key.keysym.sym);
|
||||
|
||||
bool keysCaptured = false;
|
||||
for(auto i = keyinterested.begin(); i != keyinterested.end() && continueEventHandling; i++)
|
||||
{
|
||||
if((*i)->captureThisKey(key.keysym.sym))
|
||||
for (EShortcut shortcut : shortcutsVector)
|
||||
{
|
||||
keysCaptured = true;
|
||||
break;
|
||||
if((*i)->captureThisKey(shortcut))
|
||||
{
|
||||
keysCaptured = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<CIntObject*> miCopy = keyinterested;
|
||||
for(auto i = miCopy.begin(); i != miCopy.end() && continueEventHandling; i++)
|
||||
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisKey(key.keysym.sym)))
|
||||
{
|
||||
for (EShortcut shortcut : shortcutsVector)
|
||||
{
|
||||
if (key.state == SDL_PRESSED && key.repeat == 0) // function like key_DOWN, and not like a periodic key_Pressed check
|
||||
(**i).keyPressed(key.keysym.sym);
|
||||
if (key.state == SDL_RELEASED)
|
||||
(**i).keyReleased(key.keysym.sym);
|
||||
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisKey(shortcut)))
|
||||
{
|
||||
if (key.state == SDL_PRESSED)
|
||||
(**i).keyPressed(shortcut);
|
||||
if (key.state == SDL_RELEASED)
|
||||
(**i).keyReleased(shortcut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(current.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
@ -704,6 +714,10 @@ CGuiHandler::~CGuiHandler()
|
||||
delete terminate_cond;
|
||||
}
|
||||
|
||||
ShortcutHandler & CGuiHandler::shortcutsHandler()
|
||||
{
|
||||
return *shortcutsHandlerInstance;
|
||||
}
|
||||
|
||||
void CGuiHandler::moveCursorToPosition(const Point & position)
|
||||
{
|
||||
@ -770,69 +784,6 @@ void CGuiHandler::drawFPSCounter()
|
||||
graphics->fonts[FONT_BIG]->renderTextLeft(screen, fps, Colors::YELLOW, Point(10, 10));
|
||||
}
|
||||
|
||||
SDL_Keycode CGuiHandler::arrowToNum(SDL_Keycode key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_DOWN:
|
||||
return SDLK_KP_2;
|
||||
case SDLK_UP:
|
||||
return SDLK_KP_8;
|
||||
case SDLK_LEFT:
|
||||
return SDLK_KP_4;
|
||||
case SDLK_RIGHT:
|
||||
return SDLK_KP_6;
|
||||
default:
|
||||
throw std::runtime_error("Wrong key!");
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Keycode CGuiHandler::numToDigit(SDL_Keycode key)
|
||||
{
|
||||
|
||||
#define REMOVE_KP(keyName) case SDLK_KP_ ## keyName : return SDLK_ ## keyName;
|
||||
switch(key)
|
||||
{
|
||||
REMOVE_KP(0)
|
||||
REMOVE_KP(1)
|
||||
REMOVE_KP(2)
|
||||
REMOVE_KP(3)
|
||||
REMOVE_KP(4)
|
||||
REMOVE_KP(5)
|
||||
REMOVE_KP(6)
|
||||
REMOVE_KP(7)
|
||||
REMOVE_KP(8)
|
||||
REMOVE_KP(9)
|
||||
REMOVE_KP(PERIOD)
|
||||
REMOVE_KP(MINUS)
|
||||
REMOVE_KP(PLUS)
|
||||
REMOVE_KP(EQUALS)
|
||||
|
||||
case SDLK_KP_MULTIPLY:
|
||||
return SDLK_ASTERISK;
|
||||
case SDLK_KP_DIVIDE:
|
||||
return SDLK_SLASH;
|
||||
case SDLK_KP_ENTER:
|
||||
return SDLK_RETURN;
|
||||
default:
|
||||
return SDLK_UNKNOWN;
|
||||
}
|
||||
#undef REMOVE_KP
|
||||
}
|
||||
|
||||
bool CGuiHandler::isNumKey(SDL_Keycode key, bool number)
|
||||
{
|
||||
if(number)
|
||||
return key >= SDLK_KP_1 && key <= SDLK_KP_0;
|
||||
else
|
||||
return (key >= SDLK_KP_1 && key <= SDLK_KP_0) || key == SDLK_KP_MINUS || key == SDLK_KP_PLUS || key == SDLK_KP_EQUALS;
|
||||
}
|
||||
|
||||
bool CGuiHandler::isArrowKey(SDL_Keycode key)
|
||||
{
|
||||
return key == SDLK_UP || key == SDLK_DOWN || key == SDLK_LEFT || key == SDLK_RIGHT;
|
||||
}
|
||||
|
||||
bool CGuiHandler::amIGuiThread()
|
||||
{
|
||||
return inGuiThread.get() && *inGuiThread;
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include "MouseButton.h"
|
||||
#include "../../lib/Point.h"
|
||||
|
||||
#include <SDL_keycode.h>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template <typename T> struct CondSh;
|
||||
@ -24,6 +22,7 @@ VCMI_LIB_NAMESPACE_END
|
||||
union SDL_Event;
|
||||
struct SDL_MouseMotionEvent;
|
||||
|
||||
class ShortcutHandler;
|
||||
class CFramerateManager;
|
||||
class IStatusBar;
|
||||
class CIntObject;
|
||||
@ -79,8 +78,10 @@ private:
|
||||
|
||||
std::vector<std::shared_ptr<IShowActivatable>> disposed;
|
||||
|
||||
std::unique_ptr<ShortcutHandler> shortcutsHandlerInstance;
|
||||
|
||||
std::atomic<bool> continueEventHandling;
|
||||
typedef std::list<CIntObject*> CIntObjectList;
|
||||
using CIntObjectList = std::list<CIntObject *>;
|
||||
|
||||
//active GUI elements (listening for events
|
||||
CIntObjectList lclickable;
|
||||
@ -107,14 +108,14 @@ private:
|
||||
public:
|
||||
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
||||
void handleElementDeActivate(CIntObject * elem, ui16 activityFlag);
|
||||
|
||||
public:
|
||||
//objs to blit
|
||||
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
|
||||
|
||||
/// returns current position of mouse cursor, relative to vcmi window
|
||||
const Point & getCursorPosition() const;
|
||||
|
||||
ShortcutHandler & shortcutsHandler();
|
||||
|
||||
Point screenDimensions() const;
|
||||
|
||||
/// returns true if at least one mouse button is pressed
|
||||
@ -175,10 +176,6 @@ public:
|
||||
void breakEventHandling(); //current event won't be propagated anymore
|
||||
void drawFPSCounter(); // draws the FPS to the upper left corner of the screen
|
||||
|
||||
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
|
||||
static bool isNumKey(SDL_Keycode key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits)
|
||||
static bool isArrowKey(SDL_Keycode key);
|
||||
static bool amIGuiThread();
|
||||
static void pushUserEvent(EUserEvent usercode);
|
||||
static void pushUserEvent(EUserEvent usercode, void * userdata);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "CIntObject.h"
|
||||
|
||||
#include "CGuiHandler.h"
|
||||
#include "Shortcut.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../CMT.h"
|
||||
@ -305,28 +306,23 @@ const Rect & CIntObject::center(const Point & p, bool propagate)
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool CIntObject::captureThisKey(const SDL_Keycode & key)
|
||||
bool CIntObject::captureThisKey(EShortcut key)
|
||||
{
|
||||
return captureAllKeys;
|
||||
}
|
||||
|
||||
CKeyShortcut::CKeyShortcut()
|
||||
: assignedKey(EShortcut::NONE)
|
||||
{}
|
||||
|
||||
CKeyShortcut::CKeyShortcut(int key)
|
||||
CKeyShortcut::CKeyShortcut(EShortcut key)
|
||||
: assignedKey(key)
|
||||
{
|
||||
if (key != SDLK_UNKNOWN)
|
||||
assignedKeys.insert(key);
|
||||
}
|
||||
|
||||
CKeyShortcut::CKeyShortcut(std::set<int> Keys)
|
||||
:assignedKeys(Keys)
|
||||
{}
|
||||
|
||||
void CKeyShortcut::keyPressed(const SDL_Keycode & key)
|
||||
void CKeyShortcut::keyPressed(EShortcut key)
|
||||
{
|
||||
if(vstd::contains(assignedKeys,key)
|
||||
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key)))
|
||||
if( assignedKey == key && assignedKey != EShortcut::NONE)
|
||||
{
|
||||
bool prev = mouseState(MouseButton::LEFT);
|
||||
updateMouseState(MouseButton::LEFT, true);
|
||||
@ -335,10 +331,9 @@ void CKeyShortcut::keyPressed(const SDL_Keycode & key)
|
||||
}
|
||||
}
|
||||
|
||||
void CKeyShortcut::keyReleased(const SDL_Keycode & key)
|
||||
void CKeyShortcut::keyReleased(EShortcut key)
|
||||
{
|
||||
if(vstd::contains(assignedKeys,key)
|
||||
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key)))
|
||||
if( assignedKey == key && assignedKey != EShortcut::NONE)
|
||||
{
|
||||
bool prev = mouseState(MouseButton::LEFT);
|
||||
updateMouseState(MouseButton::LEFT, false);
|
||||
|
@ -16,8 +16,7 @@
|
||||
struct SDL_Surface;
|
||||
class CGuiHandler;
|
||||
class CPicture;
|
||||
|
||||
typedef int32_t SDL_Keycode;
|
||||
enum class EShortcut;
|
||||
|
||||
using boost::logic::tribool;
|
||||
|
||||
@ -111,9 +110,9 @@ public:
|
||||
|
||||
//keyboard handling
|
||||
bool captureAllKeys; //if true, only this object should get info about pressed keys
|
||||
virtual void keyPressed(const SDL_Keycode & key){}
|
||||
virtual void keyReleased(const SDL_Keycode & key){}
|
||||
virtual bool captureThisKey(const SDL_Keycode & key); //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
|
||||
virtual void keyPressed(EShortcut key){}
|
||||
virtual void keyReleased(EShortcut key){}
|
||||
virtual bool captureThisKey(EShortcut key); //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
|
||||
|
||||
virtual void textInputed(const std::string & enteredText){};
|
||||
virtual void textEdited(const std::string & enteredText){};
|
||||
@ -190,12 +189,11 @@ public:
|
||||
class CKeyShortcut : public virtual CIntObject
|
||||
{
|
||||
public:
|
||||
std::set<int> assignedKeys;
|
||||
EShortcut assignedKey;
|
||||
CKeyShortcut();
|
||||
CKeyShortcut(int key);
|
||||
CKeyShortcut(std::set<int> Keys);
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyReleased(const SDL_Keycode & key) override;
|
||||
CKeyShortcut(EShortcut key);
|
||||
void keyPressed(EShortcut key) override;
|
||||
void keyReleased(EShortcut key) override;
|
||||
|
||||
};
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/ShortcutHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
@ -25,18 +27,6 @@
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
|
||||
static std::map<std::string, int> KeycodeMap{
|
||||
{"up", SDLK_UP},
|
||||
{"down", SDLK_DOWN},
|
||||
{"left", SDLK_LEFT},
|
||||
{"right", SDLK_RIGHT},
|
||||
{"space", SDLK_SPACE},
|
||||
{"escape", SDLK_ESCAPE},
|
||||
{"backspace", SDLK_BACKSPACE},
|
||||
{"enter", SDLK_RETURN}
|
||||
};
|
||||
|
||||
|
||||
InterfaceObjectConfigurable::InterfaceObjectConfigurable(const JsonNode & config, int used, Point offset):
|
||||
InterfaceObjectConfigurable(used, offset)
|
||||
{
|
||||
@ -211,27 +201,20 @@ std::pair<std::string, std::string> InterfaceObjectConfigurable::readHintText(co
|
||||
return result;
|
||||
}
|
||||
|
||||
int InterfaceObjectConfigurable::readKeycode(const JsonNode & config) const
|
||||
EShortcut InterfaceObjectConfigurable::readHotkey(const JsonNode & config) const
|
||||
{
|
||||
logGlobal->debug("Reading keycode");
|
||||
if(config.getType() == JsonNode::JsonType::DATA_INTEGER)
|
||||
return config.Integer();
|
||||
|
||||
if(config.getType() == JsonNode::JsonType::DATA_STRING)
|
||||
logGlobal->debug("Reading hotkey");
|
||||
|
||||
if(config.getType() != JsonNode::JsonType::DATA_STRING)
|
||||
{
|
||||
auto s = config.String();
|
||||
if(s.size() == 1) //keyboard symbol
|
||||
return s[0];
|
||||
|
||||
if (KeycodeMap.count(s))
|
||||
return KeycodeMap[s];
|
||||
|
||||
logGlobal->error("Invalid keycode '%s' in interface configuration!", config.String());
|
||||
return SDLK_UNKNOWN;
|
||||
logGlobal->error("Invalid hotket format in interface configuration! Expected string!", config.String());
|
||||
return EShortcut::NONE;
|
||||
}
|
||||
|
||||
logGlobal->error("Invalid keycode format in interface configuration! Expected string or integer!", config.String());
|
||||
return SDLK_UNKNOWN;
|
||||
EShortcut result = GH.shortcutsHandler().findShortcut(config.String());
|
||||
if (result == EShortcut::NONE)
|
||||
logGlobal->error("Invalid hotkey '%s' in interface configuration!", config.String());
|
||||
return result;;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPicture> InterfaceObjectConfigurable::buildPicture(const JsonNode & config) const
|
||||
@ -337,16 +320,27 @@ std::shared_ptr<CButton> InterfaceObjectConfigurable::buildButton(const JsonNode
|
||||
button->setImageOrder(imgOrder[0].Integer(), imgOrder[1].Integer(), imgOrder[2].Integer(), imgOrder[3].Integer());
|
||||
}
|
||||
if(!config["callback"].isNull())
|
||||
button->addCallback(std::bind(callbacks.at(config["callback"].String()), 0));
|
||||
{
|
||||
std::string callbackName = config["callback"].String();
|
||||
|
||||
if (callbacks.count(callbackName) > 0)
|
||||
button->addCallback(std::bind(callbacks.at(callbackName), 0));
|
||||
else
|
||||
logGlobal->error("Invalid callback '%s' in widget", callbackName );
|
||||
}
|
||||
if(!config["hotkey"].isNull())
|
||||
{
|
||||
if(config["hotkey"].getType() == JsonNode::JsonType::DATA_VECTOR)
|
||||
if(config["hotkey"].getType() == JsonNode::JsonType::DATA_STRING)
|
||||
{
|
||||
for(auto k : config["hotkey"].Vector())
|
||||
button->assignedKeys.insert(readKeycode(k));
|
||||
button->assignedKey = readHotkey(config["hotkey"]);
|
||||
|
||||
auto target = shortcuts.find(button->assignedKey);
|
||||
if (target != shortcuts.end())
|
||||
{
|
||||
button->addCallback(target->second.callback);
|
||||
target->second.assignedToButton = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
button->assignedKeys.insert(readKeycode(config["hotkey"]));
|
||||
}
|
||||
return button;
|
||||
}
|
||||
@ -452,3 +446,41 @@ std::shared_ptr<CIntObject> InterfaceObjectConfigurable::buildWidget(JsonNode co
|
||||
logGlobal->error("Builder with type %s is not registered", type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InterfaceObjectConfigurable::setShortcutBlocked(EShortcut shortcut, bool isBlocked)
|
||||
{
|
||||
auto target = shortcuts.find(shortcut);
|
||||
if (target == shortcuts.end())
|
||||
return;
|
||||
|
||||
target->second.blocked = isBlocked;
|
||||
|
||||
for (auto & entry : widgets)
|
||||
{
|
||||
auto button = std::dynamic_pointer_cast<CButton>(entry.second);
|
||||
|
||||
if (button && button->assignedKey == shortcut)
|
||||
button->block(isBlocked);
|
||||
}
|
||||
}
|
||||
|
||||
void InterfaceObjectConfigurable::addShortcut(EShortcut shortcut, std::function<void()> callback)
|
||||
{
|
||||
assert(shortcuts.count(shortcut) == 0);
|
||||
shortcuts[shortcut].callback = callback;
|
||||
}
|
||||
|
||||
void InterfaceObjectConfigurable::keyPressed(EShortcut key)
|
||||
{
|
||||
auto target = shortcuts.find(key);
|
||||
if (target == shortcuts.end())
|
||||
return;
|
||||
|
||||
if (target->second.assignedToButton)
|
||||
return; // will be handled by button instance
|
||||
|
||||
if (target->second.blocked)
|
||||
return;
|
||||
|
||||
target->second.callback();
|
||||
}
|
||||
|
@ -35,7 +35,14 @@ public:
|
||||
InterfaceObjectConfigurable(const JsonNode & config, int used=0, Point offset=Point());
|
||||
|
||||
protected:
|
||||
|
||||
/// Set blocked status for all buttons assotiated with provided shortcut
|
||||
void setShortcutBlocked(EShortcut shortcut, bool isBlocked);
|
||||
|
||||
/// Registers provided callback to be called whenever specified shortcut is triggered
|
||||
void addShortcut(EShortcut shortcut, std::function<void()> callback);
|
||||
|
||||
void keyPressed(EShortcut key) override;
|
||||
|
||||
using BuilderFunction = std::function<std::shared_ptr<CIntObject>(const JsonNode &)>;
|
||||
void registerBuilder(const std::string &, BuilderFunction);
|
||||
|
||||
@ -64,7 +71,7 @@ protected:
|
||||
EFonts readFont(const JsonNode &) const;
|
||||
std::string readText(const JsonNode &) const;
|
||||
std::pair<std::string, std::string> readHintText(const JsonNode &) const;
|
||||
int readKeycode(const JsonNode &) const;
|
||||
EShortcut readHotkey(const JsonNode &) const;
|
||||
|
||||
//basic widgets
|
||||
std::shared_ptr<CPicture> buildPicture(const JsonNode &) const;
|
||||
@ -82,9 +89,16 @@ protected:
|
||||
std::shared_ptr<CIntObject> buildWidget(JsonNode config) const;
|
||||
|
||||
private:
|
||||
struct ShortcutState
|
||||
{
|
||||
std::function<void()> callback;
|
||||
mutable bool assignedToButton = false;
|
||||
bool blocked = false;
|
||||
};
|
||||
|
||||
int unnamedObjectId = 0;
|
||||
std::map<std::string, BuilderFunction> builders;
|
||||
std::map<std::string, std::shared_ptr<CIntObject>> widgets;
|
||||
std::map<std::string, std::function<void(int)>> callbacks;
|
||||
std::map<EShortcut, ShortcutState> shortcuts;
|
||||
};
|
||||
|
156
client/gui/Shortcut.h
Normal file
156
client/gui/Shortcut.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Shortcut.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
enum class EShortcut
|
||||
{
|
||||
NONE,
|
||||
|
||||
// Global hotkeys that are available in multiple dialogs
|
||||
GLOBAL_ACCEPT, // Return - Accept query
|
||||
GLOBAL_CANCEL, // Escape - Cancel query
|
||||
GLOBAL_RETURN, // Enter, Escape - Close current window and return to previous view
|
||||
GLOBAL_FULLSCREEN, // F4 - TODO: remove hardcoded check for key
|
||||
GLOBAL_OPTIONS, // 'O' - Open System Options dialog
|
||||
GLOBAL_BACKSPACE, // Backspace - erase last symbol in text input
|
||||
GLOBAL_MOVE_FOCUS, // Tab - move focus to next text input
|
||||
|
||||
// Movement hotkeys, usually - for moving through lists with slider
|
||||
MOVE_LEFT,
|
||||
MOVE_RIGHT,
|
||||
MOVE_UP,
|
||||
MOVE_DOWN,
|
||||
MOVE_FIRST,
|
||||
MOVE_LAST,
|
||||
MOVE_PAGE_UP,
|
||||
MOVE_PAGE_DOWN,
|
||||
|
||||
// Element selection - for multiple choice dialog popups
|
||||
SELECT_INDEX_1,
|
||||
SELECT_INDEX_2,
|
||||
SELECT_INDEX_3,
|
||||
SELECT_INDEX_4,
|
||||
SELECT_INDEX_5,
|
||||
SELECT_INDEX_6,
|
||||
SELECT_INDEX_7,
|
||||
SELECT_INDEX_8,
|
||||
|
||||
// Main menu hotkeys - for navigation between main menu windows
|
||||
MAIN_MENU_NEW_GAME,
|
||||
MAIN_MENU_LOAD_GAME,
|
||||
MAIN_MENU_HIGH_SCORES,
|
||||
MAIN_MENU_CREDITS,
|
||||
MAIN_MENU_BACK,
|
||||
MAIN_MENU_QUIT,
|
||||
MAIN_MENU_SINGLEPLAYER,
|
||||
MAIN_MENU_MULTIPLAYER,
|
||||
MAIN_MENU_CAMPAIGN,
|
||||
MAIN_MENU_TUTORIAL,
|
||||
MAIN_MENU_CAMPAIGN_SOD,
|
||||
MAIN_MENU_CAMPAIGN_ROE,
|
||||
MAIN_MENU_CAMPAIGN_AB,
|
||||
MAIN_MENU_CAMPAIGN_CUSTOM,
|
||||
|
||||
// Game lobby / scenario selection
|
||||
LOBBY_BEGIN_GAME, // b, Return
|
||||
LOBBY_LOAD_GAME, // l, Return
|
||||
LOBBY_SAVE_GAME, // s, Return
|
||||
LOBBY_RANDOM_MAP, // Open random map tab
|
||||
LOBBY_HIDE_CHAT,
|
||||
LOBBY_ADDITIONAL_OPTIONS, // Open additional options tab
|
||||
LOBBY_SELECT_SCENARIO, // Open map list tab
|
||||
|
||||
// In-game hotkeys, require game state but may be available in windows other than adventure map
|
||||
GAME_END_TURN,
|
||||
GAME_LOAD_GAME,
|
||||
GAME_SAVE_GAME,
|
||||
GAME_RESTART_GAME,
|
||||
GAME_TO_MAIN_MENU,
|
||||
GAME_QUIT_GAME,
|
||||
GAME_OPEN_MARKETPLACE,
|
||||
GAME_OPEN_THIEVES_GUILD,
|
||||
GAME_ACTIVATE_CONSOLE, // Tab, activates in-game console
|
||||
|
||||
// Adventure map screen
|
||||
ADVENTURE_GAME_OPTIONS, // 'o', Open CAdventureOptions window
|
||||
ADVENTURE_TOGGLE_GRID, // F6, Toggles map grid
|
||||
ADVENTURE_TOGGLE_SLEEP, // z,w, Toggles hero sleep status
|
||||
ADVENTURE_MOVE_HERO, // Moves hero alongside set path
|
||||
ADVENTURE_VISIT_OBJECT, // Revisits object hero is standing on
|
||||
ADVENTURE_VIEW_SELECTED,// Open window with currently selected hero/town
|
||||
ADVENTURE_NEXT_TOWN,
|
||||
ADVENTURE_NEXT_HERO,
|
||||
ADVENTURE_NEXT_OBJECT, // TODO: context-sensitive next object - select next hero/town, depending on current selection
|
||||
ADVENTURE_FIRST_TOWN, // TODO: select first available town in the list
|
||||
ADVENTURE_FIRST_HERO, // TODO: select first available hero in the list
|
||||
ADVENTURE_VIEW_SCENARIO,// View Scenario Information window
|
||||
ADVENTURE_DIG_GRAIL,
|
||||
ADVENTURE_VIEW_PUZZLE,
|
||||
ADVENTURE_VIEW_WORLD,
|
||||
ADVENTURE_TOGGLE_MAP_LEVEL,
|
||||
ADVENTURE_KINGDOM_OVERVIEW,
|
||||
ADVENTURE_QUEST_LOG,
|
||||
ADVENTURE_CAST_SPELL,
|
||||
ADVENTURE_END_TURN,
|
||||
ADVENTURE_THIEVES_GUILD,
|
||||
|
||||
// Move hero one tile in specified direction. Bound to cursors & numpad buttons
|
||||
ADVENTURE_MOVE_HERO_SW,
|
||||
ADVENTURE_MOVE_HERO_SS,
|
||||
ADVENTURE_MOVE_HERO_SE,
|
||||
ADVENTURE_MOVE_HERO_WW,
|
||||
ADVENTURE_MOVE_HERO_EE,
|
||||
ADVENTURE_MOVE_HERO_NW,
|
||||
ADVENTURE_MOVE_HERO_NN,
|
||||
ADVENTURE_MOVE_HERO_NE,
|
||||
|
||||
// Battle screen
|
||||
BATTLE_TOGGLE_QUEUE,
|
||||
BATTLE_USE_CREATURE_SPELL,
|
||||
BATTLE_SURRENDER,
|
||||
BATTLE_RETREAT,
|
||||
BATTLE_AUTOCOMBAT,
|
||||
BATTLE_CAST_SPELL,
|
||||
BATTLE_WAIT,
|
||||
BATTLE_DEFEND,
|
||||
BATTLE_CONSOLE_UP,
|
||||
BATTLE_CONSOLE_DOWN,
|
||||
BATTLE_TACTICS_NEXT,
|
||||
BATTLE_TACTICS_END,
|
||||
BATTLE_SELECT_ACTION, // Alternative actions toggle
|
||||
|
||||
// Town screen
|
||||
TOWN_OPEN_TAVERN,
|
||||
TOWN_SWAP_ARMIES, // Swap garrisoned and visiting armies
|
||||
|
||||
// Creature & creature recruitment screen
|
||||
RECRUITMENT_MAX, // Set number of creatures to recruit to max
|
||||
RECRUITMENT_MIN, // Set number of creatures to recruit to min (1)
|
||||
RECRUITMENT_UPGRADE, // Upgrade current creature
|
||||
RECRUITMENT_UPGRADE_ALL, // Upgrade all creatures (Hill Fort / Skeleton Transformer)
|
||||
|
||||
// Kingdom Overview window
|
||||
KINGDOM_HEROES_TAB,
|
||||
KINGDOM_TOWNS_TAB,
|
||||
|
||||
// Hero screen
|
||||
HERO_DISMISS,
|
||||
HERO_COMMANDER,
|
||||
HERO_LOOSE_FORMATION,
|
||||
HERO_TIGHT_FORMATION,
|
||||
HERO_TOGGLE_TACTICS, // b
|
||||
|
||||
// Spellbook screen
|
||||
SPELLBOOK_TAB_ADVENTURE,
|
||||
SPELLBOOK_TAB_COMBAT,
|
||||
|
||||
AFTER_LAST
|
||||
};
|
||||
|
362
client/gui/ShortcutHandler.cpp
Normal file
362
client/gui/ShortcutHandler.cpp
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* ShortcutHandler.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "ShortcutHandler.h"
|
||||
#include "Shortcut.h"
|
||||
#include <SDL_keycode.h>
|
||||
|
||||
std::vector<EShortcut> ShortcutHandler::translateKeycode(SDL_Keycode key) const
|
||||
{
|
||||
static const std::multimap<SDL_Keycode, EShortcut> keyToShortcut = {
|
||||
{SDLK_RETURN, EShortcut::GLOBAL_ACCEPT },
|
||||
{SDLK_KP_ENTER, EShortcut::GLOBAL_ACCEPT },
|
||||
{SDLK_ESCAPE, EShortcut::GLOBAL_CANCEL },
|
||||
{SDLK_RETURN, EShortcut::GLOBAL_RETURN },
|
||||
{SDLK_KP_ENTER, EShortcut::GLOBAL_RETURN },
|
||||
{SDLK_ESCAPE, EShortcut::GLOBAL_RETURN },
|
||||
{SDLK_F4, EShortcut::GLOBAL_FULLSCREEN },
|
||||
{SDLK_BACKSPACE, EShortcut::GLOBAL_BACKSPACE },
|
||||
{SDLK_TAB, EShortcut::GLOBAL_MOVE_FOCUS },
|
||||
{SDLK_o, EShortcut::GLOBAL_OPTIONS },
|
||||
{SDLK_LEFT, EShortcut::MOVE_LEFT },
|
||||
{SDLK_RIGHT, EShortcut::MOVE_RIGHT },
|
||||
{SDLK_UP, EShortcut::MOVE_UP },
|
||||
{SDLK_DOWN, EShortcut::MOVE_DOWN },
|
||||
{SDLK_HOME, EShortcut::MOVE_FIRST },
|
||||
{SDLK_END, EShortcut::MOVE_LAST },
|
||||
{SDLK_PAGEUP, EShortcut::MOVE_PAGE_UP },
|
||||
{SDLK_PAGEDOWN, EShortcut::MOVE_PAGE_DOWN },
|
||||
{SDLK_1, EShortcut::SELECT_INDEX_1 },
|
||||
{SDLK_2, EShortcut::SELECT_INDEX_2 },
|
||||
{SDLK_3, EShortcut::SELECT_INDEX_3 },
|
||||
{SDLK_4, EShortcut::SELECT_INDEX_4 },
|
||||
{SDLK_5, EShortcut::SELECT_INDEX_5 },
|
||||
{SDLK_6, EShortcut::SELECT_INDEX_6 },
|
||||
{SDLK_7, EShortcut::SELECT_INDEX_7 },
|
||||
{SDLK_8, EShortcut::SELECT_INDEX_8 },
|
||||
{SDLK_n, EShortcut::MAIN_MENU_NEW_GAME },
|
||||
{SDLK_l, EShortcut::MAIN_MENU_LOAD_GAME },
|
||||
{SDLK_h, EShortcut::MAIN_MENU_HIGH_SCORES },
|
||||
{SDLK_c, EShortcut::MAIN_MENU_CREDITS },
|
||||
{SDLK_q, EShortcut::MAIN_MENU_QUIT },
|
||||
{SDLK_b, EShortcut::MAIN_MENU_BACK },
|
||||
{SDLK_s, EShortcut::MAIN_MENU_SINGLEPLAYER },
|
||||
{SDLK_m, EShortcut::MAIN_MENU_MULTIPLAYER },
|
||||
{SDLK_c, EShortcut::MAIN_MENU_CAMPAIGN },
|
||||
{SDLK_t, EShortcut::MAIN_MENU_TUTORIAL },
|
||||
{SDLK_s, EShortcut::MAIN_MENU_CAMPAIGN_SOD },
|
||||
{SDLK_r, EShortcut::MAIN_MENU_CAMPAIGN_ROE },
|
||||
{SDLK_a, EShortcut::MAIN_MENU_CAMPAIGN_AB },
|
||||
{SDLK_c, EShortcut::MAIN_MENU_CAMPAIGN_CUSTOM },
|
||||
{SDLK_b, EShortcut::LOBBY_BEGIN_GAME },
|
||||
{SDLK_RETURN, EShortcut::LOBBY_BEGIN_GAME },
|
||||
{SDLK_KP_ENTER, EShortcut::LOBBY_BEGIN_GAME },
|
||||
{SDLK_l, EShortcut::LOBBY_LOAD_GAME },
|
||||
{SDLK_RETURN, EShortcut::LOBBY_LOAD_GAME },
|
||||
{SDLK_KP_ENTER, EShortcut::LOBBY_LOAD_GAME },
|
||||
{SDLK_s, EShortcut::LOBBY_SAVE_GAME },
|
||||
{SDLK_r, EShortcut::LOBBY_RANDOM_MAP },
|
||||
{SDLK_h, EShortcut::LOBBY_HIDE_CHAT },
|
||||
{SDLK_a, EShortcut::LOBBY_ADDITIONAL_OPTIONS },
|
||||
{SDLK_s, EShortcut::LOBBY_SELECT_SCENARIO },
|
||||
{SDLK_e, EShortcut::GAME_END_TURN },
|
||||
{SDLK_l, EShortcut::GAME_LOAD_GAME },
|
||||
{SDLK_s, EShortcut::GAME_SAVE_GAME },
|
||||
{SDLK_r, EShortcut::GAME_RESTART_GAME },
|
||||
{SDLK_m, EShortcut::GAME_TO_MAIN_MENU },
|
||||
{SDLK_q, EShortcut::GAME_QUIT_GAME },
|
||||
{SDLK_t, EShortcut::GAME_OPEN_MARKETPLACE },
|
||||
{SDLK_g, EShortcut::GAME_OPEN_THIEVES_GUILD },
|
||||
{SDLK_TAB, EShortcut::GAME_ACTIVATE_CONSOLE },
|
||||
{SDLK_o, EShortcut::ADVENTURE_GAME_OPTIONS },
|
||||
{SDLK_F6, EShortcut::ADVENTURE_TOGGLE_GRID },
|
||||
{SDLK_z, EShortcut::ADVENTURE_TOGGLE_SLEEP },
|
||||
{SDLK_w, EShortcut::ADVENTURE_TOGGLE_SLEEP },
|
||||
{SDLK_m, EShortcut::ADVENTURE_MOVE_HERO },
|
||||
{SDLK_SPACE, EShortcut::ADVENTURE_VISIT_OBJECT },
|
||||
{SDLK_KP_1, EShortcut::ADVENTURE_MOVE_HERO_SW },
|
||||
{SDLK_KP_2, EShortcut::ADVENTURE_MOVE_HERO_SS },
|
||||
{SDLK_KP_3, EShortcut::ADVENTURE_MOVE_HERO_SE },
|
||||
{SDLK_KP_4, EShortcut::ADVENTURE_MOVE_HERO_WW },
|
||||
{SDLK_KP_6, EShortcut::ADVENTURE_MOVE_HERO_EE },
|
||||
{SDLK_KP_7, EShortcut::ADVENTURE_MOVE_HERO_NW },
|
||||
{SDLK_KP_8, EShortcut::ADVENTURE_MOVE_HERO_NN },
|
||||
{SDLK_KP_9, EShortcut::ADVENTURE_MOVE_HERO_NE },
|
||||
{SDLK_DOWN, EShortcut::ADVENTURE_MOVE_HERO_SS },
|
||||
{SDLK_LEFT, EShortcut::ADVENTURE_MOVE_HERO_WW },
|
||||
{SDLK_RIGHT, EShortcut::ADVENTURE_MOVE_HERO_EE },
|
||||
{SDLK_UP, EShortcut::ADVENTURE_MOVE_HERO_NN },
|
||||
{SDLK_RETURN, EShortcut::ADVENTURE_VIEW_SELECTED },
|
||||
{SDLK_KP_ENTER, EShortcut::ADVENTURE_VIEW_SELECTED },
|
||||
// {SDLK_, EShortcut::ADVENTURE_NEXT_OBJECT },
|
||||
{SDLK_t, EShortcut::ADVENTURE_NEXT_TOWN },
|
||||
{SDLK_h, EShortcut::ADVENTURE_NEXT_HERO },
|
||||
// {SDLK_, EShortcut::ADVENTURE_FIRST_TOWN },
|
||||
// {SDLK_, EShortcut::ADVENTURE_FIRST_HERO },
|
||||
{SDLK_i, EShortcut::ADVENTURE_VIEW_SCENARIO },
|
||||
{SDLK_d, EShortcut::ADVENTURE_DIG_GRAIL },
|
||||
{SDLK_p, EShortcut::ADVENTURE_VIEW_PUZZLE },
|
||||
{SDLK_v, EShortcut::ADVENTURE_VIEW_WORLD },
|
||||
{SDLK_u, EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL},
|
||||
{SDLK_k, EShortcut::ADVENTURE_KINGDOM_OVERVIEW},
|
||||
{SDLK_q, EShortcut::ADVENTURE_QUEST_LOG },
|
||||
{SDLK_c, EShortcut::ADVENTURE_CAST_SPELL },
|
||||
{SDLK_e, EShortcut::ADVENTURE_END_TURN },
|
||||
{SDLK_g, EShortcut::ADVENTURE_THIEVES_GUILD },
|
||||
{SDLK_q, EShortcut::BATTLE_TOGGLE_QUEUE },
|
||||
{SDLK_c, EShortcut::BATTLE_USE_CREATURE_SPELL },
|
||||
{SDLK_s, EShortcut::BATTLE_SURRENDER },
|
||||
{SDLK_r, EShortcut::BATTLE_RETREAT },
|
||||
{SDLK_a, EShortcut::BATTLE_AUTOCOMBAT },
|
||||
{SDLK_c, EShortcut::BATTLE_CAST_SPELL },
|
||||
{SDLK_w, EShortcut::BATTLE_WAIT },
|
||||
{SDLK_d, EShortcut::BATTLE_DEFEND },
|
||||
{SDLK_SPACE, EShortcut::BATTLE_DEFEND },
|
||||
{SDLK_UP, EShortcut::BATTLE_CONSOLE_UP },
|
||||
{SDLK_DOWN, EShortcut::BATTLE_CONSOLE_DOWN },
|
||||
{SDLK_SPACE, EShortcut::BATTLE_TACTICS_NEXT },
|
||||
{SDLK_RETURN, EShortcut::BATTLE_TACTICS_END },
|
||||
{SDLK_KP_ENTER, EShortcut::BATTLE_TACTICS_END },
|
||||
{SDLK_s, EShortcut::BATTLE_SELECT_ACTION },
|
||||
{SDLK_t, EShortcut::TOWN_OPEN_TAVERN },
|
||||
{SDLK_SPACE, EShortcut::TOWN_SWAP_ARMIES },
|
||||
{SDLK_END, EShortcut::RECRUITMENT_MAX },
|
||||
{SDLK_HOME, EShortcut::RECRUITMENT_MIN },
|
||||
{SDLK_u, EShortcut::RECRUITMENT_UPGRADE },
|
||||
{SDLK_a, EShortcut::RECRUITMENT_UPGRADE_ALL },
|
||||
{SDLK_u, EShortcut::RECRUITMENT_UPGRADE_ALL },
|
||||
{SDLK_h, EShortcut::KINGDOM_HEROES_TAB },
|
||||
{SDLK_t, EShortcut::KINGDOM_TOWNS_TAB },
|
||||
{SDLK_d, EShortcut::HERO_DISMISS },
|
||||
{SDLK_c, EShortcut::HERO_COMMANDER },
|
||||
{SDLK_l, EShortcut::HERO_LOOSE_FORMATION },
|
||||
{SDLK_t, EShortcut::HERO_TIGHT_FORMATION },
|
||||
{SDLK_b, EShortcut::HERO_TOGGLE_TACTICS },
|
||||
{SDLK_a, EShortcut::SPELLBOOK_TAB_ADVENTURE },
|
||||
{SDLK_c, EShortcut::SPELLBOOK_TAB_COMBAT }
|
||||
};
|
||||
|
||||
auto range = keyToShortcut.equal_range(key);
|
||||
|
||||
// FIXME: some code expects calls to keyPressed / captureThisKey even without defined hotkeys
|
||||
if (range.first == range.second)
|
||||
return {EShortcut::NONE};
|
||||
|
||||
std::vector<EShortcut> result;
|
||||
|
||||
for (auto it = range.first; it != range.second; ++it)
|
||||
result.push_back(it->second);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
|
||||
{
|
||||
static const std::map<std::string, EShortcut> shortcutNames = {
|
||||
{"globalAccept", EShortcut::GLOBAL_ACCEPT },
|
||||
{"globalCancel", EShortcut::GLOBAL_CANCEL },
|
||||
{"globalReturn", EShortcut::GLOBAL_RETURN },
|
||||
{"globalFullscreen", EShortcut::GLOBAL_FULLSCREEN },
|
||||
{"globalOptions", EShortcut::GLOBAL_OPTIONS },
|
||||
{"globalBackspace", EShortcut::GLOBAL_BACKSPACE },
|
||||
{"globalMoveFocus", EShortcut::GLOBAL_MOVE_FOCUS },
|
||||
{"moveLeft", EShortcut::MOVE_LEFT },
|
||||
{"moveRight", EShortcut::MOVE_RIGHT },
|
||||
{"moveUp", EShortcut::MOVE_UP },
|
||||
{"moveDown", EShortcut::MOVE_DOWN },
|
||||
{"moveFirst", EShortcut::MOVE_FIRST },
|
||||
{"moveLast", EShortcut::MOVE_LAST },
|
||||
{"movePageUp", EShortcut::MOVE_PAGE_UP },
|
||||
{"movePageDown", EShortcut::MOVE_PAGE_DOWN },
|
||||
{"selectIndex1", EShortcut::SELECT_INDEX_1 },
|
||||
{"selectIndex2", EShortcut::SELECT_INDEX_2 },
|
||||
{"selectIndex3", EShortcut::SELECT_INDEX_3 },
|
||||
{"selectIndex4", EShortcut::SELECT_INDEX_4 },
|
||||
{"selectIndex5", EShortcut::SELECT_INDEX_5 },
|
||||
{"selectIndex6", EShortcut::SELECT_INDEX_6 },
|
||||
{"selectIndex7", EShortcut::SELECT_INDEX_7 },
|
||||
{"selectIndex8", EShortcut::SELECT_INDEX_8 },
|
||||
{"mainMenuNewGame", EShortcut::MAIN_MENU_NEW_GAME },
|
||||
{"mainMenuLoadGame", EShortcut::MAIN_MENU_LOAD_GAME },
|
||||
{"mainMenuHighScores", EShortcut::MAIN_MENU_HIGH_SCORES },
|
||||
{"mainMenuCredits", EShortcut::MAIN_MENU_CREDITS },
|
||||
{"mainMenuQuit", EShortcut::MAIN_MENU_QUIT },
|
||||
{"mainMenuBack", EShortcut::MAIN_MENU_BACK },
|
||||
{"mainMenuSingleplayer", EShortcut::MAIN_MENU_SINGLEPLAYER },
|
||||
{"mainMenuMultiplayer", EShortcut::MAIN_MENU_MULTIPLAYER },
|
||||
{"mainMenuCampaign", EShortcut::MAIN_MENU_CAMPAIGN },
|
||||
{"mainMenuTutorial", EShortcut::MAIN_MENU_TUTORIAL },
|
||||
{"mainMenuCampaignSod", EShortcut::MAIN_MENU_CAMPAIGN_SOD },
|
||||
{"mainMenuCampaignRoe", EShortcut::MAIN_MENU_CAMPAIGN_ROE },
|
||||
{"mainMenuCampaignAb", EShortcut::MAIN_MENU_CAMPAIGN_AB },
|
||||
{"mainMenuCampaignCustom", EShortcut::MAIN_MENU_CAMPAIGN_CUSTOM },
|
||||
{"lobbyBeginGame", EShortcut::LOBBY_BEGIN_GAME },
|
||||
{"lobbyLoadGame", EShortcut::LOBBY_LOAD_GAME },
|
||||
{"lobbySaveGame", EShortcut::LOBBY_SAVE_GAME },
|
||||
{"lobbyRandomMap", EShortcut::LOBBY_RANDOM_MAP },
|
||||
{"lobbyHideChat", EShortcut::LOBBY_HIDE_CHAT },
|
||||
{"lobbyAdditionalOptions", EShortcut::LOBBY_ADDITIONAL_OPTIONS },
|
||||
{"lobbySelectScenario", EShortcut::LOBBY_SELECT_SCENARIO },
|
||||
{"gameEndTurn", EShortcut::GAME_END_TURN },
|
||||
{"gameLoadGame", EShortcut::GAME_LOAD_GAME },
|
||||
{"gameSaveGame", EShortcut::GAME_SAVE_GAME },
|
||||
{"gameRestartGame", EShortcut::GAME_RESTART_GAME },
|
||||
{"gameMainMenu", EShortcut::GAME_TO_MAIN_MENU },
|
||||
{"gameQuitGame", EShortcut::GAME_QUIT_GAME },
|
||||
{"gameOpenMarketplace", EShortcut::GAME_OPEN_MARKETPLACE },
|
||||
{"gameOpenThievesGuild", EShortcut::GAME_OPEN_THIEVES_GUILD },
|
||||
{"gameActivateConsole", EShortcut::GAME_ACTIVATE_CONSOLE },
|
||||
{"adventureGameOptions", EShortcut::ADVENTURE_GAME_OPTIONS },
|
||||
{"adventureToggleGrid", EShortcut::ADVENTURE_TOGGLE_GRID },
|
||||
{"adventureToggleSleep", EShortcut::ADVENTURE_TOGGLE_SLEEP },
|
||||
{"adventureMoveHero", EShortcut::ADVENTURE_MOVE_HERO },
|
||||
{"adventureVisitObject", EShortcut::ADVENTURE_VISIT_OBJECT },
|
||||
{"adventureMoveHeroSW", EShortcut::ADVENTURE_MOVE_HERO_SW },
|
||||
{"adventureMoveHeroSS", EShortcut::ADVENTURE_MOVE_HERO_SS },
|
||||
{"adventureMoveHeroSE", EShortcut::ADVENTURE_MOVE_HERO_SE },
|
||||
{"adventureMoveHeroWW", EShortcut::ADVENTURE_MOVE_HERO_WW },
|
||||
{"adventureMoveHeroEE", EShortcut::ADVENTURE_MOVE_HERO_EE },
|
||||
{"adventureMoveHeroNW", EShortcut::ADVENTURE_MOVE_HERO_NW },
|
||||
{"adventureMoveHeroNN", EShortcut::ADVENTURE_MOVE_HERO_NN },
|
||||
{"adventureMoveHeroNE", EShortcut::ADVENTURE_MOVE_HERO_NE },
|
||||
{"adventureViewSelected", EShortcut::ADVENTURE_VIEW_SELECTED },
|
||||
{"adventureNextObject", EShortcut::ADVENTURE_NEXT_OBJECT },
|
||||
{"adventureNextTown", EShortcut::ADVENTURE_NEXT_TOWN },
|
||||
{"adventureNextHero", EShortcut::ADVENTURE_NEXT_HERO },
|
||||
{"adventureFirstTown", EShortcut::ADVENTURE_FIRST_TOWN },
|
||||
{"adventureFirstHero", EShortcut::ADVENTURE_FIRST_HERO },
|
||||
{"adventureViewScenario", EShortcut::ADVENTURE_VIEW_SCENARIO },
|
||||
{"adventureDigGrail", EShortcut::ADVENTURE_DIG_GRAIL },
|
||||
{"adventureViewPuzzle", EShortcut::ADVENTURE_VIEW_PUZZLE },
|
||||
{"adventureViewWorld", EShortcut::ADVENTURE_VIEW_WORLD },
|
||||
{"adventureToggleMapLevel", EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL},
|
||||
{"adventureKingdomOverview", EShortcut::ADVENTURE_KINGDOM_OVERVIEW},
|
||||
{"adventureQuestLog", EShortcut::ADVENTURE_QUEST_LOG },
|
||||
{"adventureCastSpell", EShortcut::ADVENTURE_CAST_SPELL },
|
||||
{"adventureEndTurn", EShortcut::ADVENTURE_END_TURN },
|
||||
{"adventureThievesGuild", EShortcut::ADVENTURE_THIEVES_GUILD },
|
||||
{"battleToggleQueue", EShortcut::BATTLE_TOGGLE_QUEUE },
|
||||
{"battleUseCreatureSpell", EShortcut::BATTLE_USE_CREATURE_SPELL },
|
||||
{"battleSurrender", EShortcut::BATTLE_SURRENDER },
|
||||
{"battleRetreat", EShortcut::BATTLE_RETREAT },
|
||||
{"battleAutocombat", EShortcut::BATTLE_AUTOCOMBAT },
|
||||
{"battleCastSpell", EShortcut::BATTLE_CAST_SPELL },
|
||||
{"battleWait", EShortcut::BATTLE_WAIT },
|
||||
{"battleDefend", EShortcut::BATTLE_DEFEND },
|
||||
{"battleConsoleUp", EShortcut::BATTLE_CONSOLE_UP },
|
||||
{"battleConsoleDown", EShortcut::BATTLE_CONSOLE_DOWN },
|
||||
{"battleTacticsNext", EShortcut::BATTLE_TACTICS_NEXT },
|
||||
{"battleTacticsEnd", EShortcut::BATTLE_TACTICS_END },
|
||||
{"battleSelectAction", EShortcut::BATTLE_SELECT_ACTION },
|
||||
{"townOpenTavern", EShortcut::TOWN_OPEN_TAVERN },
|
||||
{"townSwapArmies", EShortcut::TOWN_SWAP_ARMIES },
|
||||
{"recruitmentMax", EShortcut::RECRUITMENT_MAX },
|
||||
{"recruitmentMin", EShortcut::RECRUITMENT_MIN },
|
||||
{"recruitmentUpgrade", EShortcut::RECRUITMENT_UPGRADE },
|
||||
{"recruitmentUpgradeAll", EShortcut::RECRUITMENT_UPGRADE_ALL },
|
||||
{"kingdomHeroesTab", EShortcut::KINGDOM_HEROES_TAB },
|
||||
{"kingdomTownsTab", EShortcut::KINGDOM_TOWNS_TAB },
|
||||
{"heroDismiss", EShortcut::HERO_DISMISS },
|
||||
{"heroCommander", EShortcut::HERO_COMMANDER },
|
||||
{"heroLooseFormation", EShortcut::HERO_LOOSE_FORMATION },
|
||||
{"heroTightFormation", EShortcut::HERO_TIGHT_FORMATION },
|
||||
{"heroToggleTactics", EShortcut::HERO_TOGGLE_TACTICS },
|
||||
{"spellbookTabAdventure", EShortcut::SPELLBOOK_TAB_ADVENTURE },
|
||||
{"spellbookTabCombat", EShortcut::SPELLBOOK_TAB_COMBAT }
|
||||
};
|
||||
|
||||
if (shortcutNames.count(identifier))
|
||||
return shortcutNames.at(identifier);
|
||||
return EShortcut::NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
24
client/gui/ShortcutHandler.h
Normal file
24
client/gui/ShortcutHandler.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* ShortcutHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class EShortcut;
|
||||
using SDL_Keycode = int32_t;
|
||||
|
||||
class ShortcutHandler
|
||||
{
|
||||
public:
|
||||
/// returns list of shortcuts assigned to provided SDL keycode
|
||||
std::vector<EShortcut> translateKeycode(SDL_Keycode key) const;
|
||||
|
||||
/// attempts to find shortcut by its unique identifier. Returns EShortcut::NONE on failure
|
||||
EShortcut findShortcut(const std::string & identifier ) const;
|
||||
};
|
@ -33,6 +33,7 @@
|
||||
#include "../render/IImage.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
@ -67,9 +68,9 @@ CBonusSelection::CBonusSelection()
|
||||
|
||||
panelBackground = std::make_shared<CPicture>("CAMPBRF.BMP", 456, 6);
|
||||
|
||||
buttonStart = std::make_shared<CButton>(Point(475, 536), "CBBEGIB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::startMap, this), SDLK_RETURN);
|
||||
buttonRestart = std::make_shared<CButton>(Point(475, 536), "CBRESTB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::restartMap, this), SDLK_RETURN);
|
||||
buttonBack = std::make_shared<CButton>(Point(624, 536), "CBCANCB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::goBack, this), SDLK_ESCAPE);
|
||||
buttonStart = std::make_shared<CButton>(Point(475, 536), "CBBEGIB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::startMap, this), EShortcut::GLOBAL_ACCEPT);
|
||||
buttonRestart = std::make_shared<CButton>(Point(475, 536), "CBRESTB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::restartMap, this), EShortcut::GLOBAL_ACCEPT);
|
||||
buttonBack = std::make_shared<CButton>(Point(624, 536), "CBCANCB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::goBack, this), EShortcut::GLOBAL_CANCEL);
|
||||
|
||||
campaignName = std::make_shared<CLabel>(481, 28, FONT_BIG, ETextAlignment::TOPLEFT, Colors::YELLOW, CSH->si->getCampaignName());
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../CServerHandler.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
|
||||
@ -40,17 +41,17 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
{
|
||||
tabSel->callOnSelect = std::bind(&IServerAPI::setMapInfo, CSH, _1, nullptr);
|
||||
|
||||
buttonSelect = std::make_shared<CButton>(Point(411, 80), "GSPBUTT.DEF", CGI->generaltexth->zelp[45], 0, SDLK_s);
|
||||
buttonSelect = std::make_shared<CButton>(Point(411, 80), "GSPBUTT.DEF", CGI->generaltexth->zelp[45], 0, EShortcut::LOBBY_SELECT_SCENARIO);
|
||||
buttonSelect->addCallback([&]()
|
||||
{
|
||||
toggleTab(tabSel);
|
||||
CSH->setMapInfo(tabSel->getSelectedMapInfo());
|
||||
});
|
||||
|
||||
buttonOptions = std::make_shared<CButton>(Point(411, 510), "GSPBUTT.DEF", CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabOpt), SDLK_a);
|
||||
buttonOptions = std::make_shared<CButton>(Point(411, 510), "GSPBUTT.DEF", CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabOpt), EShortcut::LOBBY_ADDITIONAL_OPTIONS);
|
||||
};
|
||||
|
||||
buttonChat = std::make_shared<CButton>(Point(619, 83), "GSPBUT2.DEF", CGI->generaltexth->zelp[48], std::bind(&CLobbyScreen::toggleChat, this), SDLK_h);
|
||||
buttonChat = std::make_shared<CButton>(Point(619, 83), "GSPBUT2.DEF", CGI->generaltexth->zelp[48], std::bind(&CLobbyScreen::toggleChat, this), EShortcut::LOBBY_HIDE_CHAT);
|
||||
buttonChat->addTextOverlay(CGI->generaltexth->allTexts[532], FONT_SMALL);
|
||||
|
||||
switch(screenType)
|
||||
@ -60,7 +61,7 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
tabOpt = std::make_shared<OptionsTab>();
|
||||
tabRand = std::make_shared<RandomMapTab>();
|
||||
tabRand->mapInfoChanged += std::bind(&IServerAPI::setMapInfo, CSH, _1, _2);
|
||||
buttonRMG = std::make_shared<CButton>(Point(411, 105), "GSPBUTT.DEF", CGI->generaltexth->zelp[47], 0, SDLK_r);
|
||||
buttonRMG = std::make_shared<CButton>(Point(411, 105), "GSPBUTT.DEF", CGI->generaltexth->zelp[47], 0, EShortcut::LOBBY_RANDOM_MAP);
|
||||
buttonRMG->addCallback([&]()
|
||||
{
|
||||
toggleTab(tabRand);
|
||||
@ -69,30 +70,28 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
|
||||
card->iconDifficulty->addCallback(std::bind(&IServerAPI::setDifficulty, CSH, _1));
|
||||
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRBEG.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), SDLK_b);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRBEG.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_BEGIN_GAME);
|
||||
initLobby();
|
||||
break;
|
||||
}
|
||||
case ESelectionScreen::loadGame:
|
||||
{
|
||||
tabOpt = std::make_shared<OptionsTab>();
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRLOD.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), SDLK_l);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRLOD.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_LOAD_GAME);
|
||||
initLobby();
|
||||
break;
|
||||
}
|
||||
case ESelectionScreen::campaignList:
|
||||
tabSel->callOnSelect = std::bind(&IServerAPI::setMapInfo, CSH, _1, nullptr);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRLOD.DEF", CButton::tooltip(), std::bind(&CLobbyScreen::startCampaign, this), SDLK_b);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRLOD.DEF", CButton::tooltip(), std::bind(&CLobbyScreen::startCampaign, this), EShortcut::LOBBY_BEGIN_GAME);
|
||||
break;
|
||||
}
|
||||
|
||||
buttonStart->assignedKeys.insert(SDLK_RETURN);
|
||||
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [&]()
|
||||
{
|
||||
CSH->sendClientDisconnecting();
|
||||
close();
|
||||
}, SDLK_ESCAPE);
|
||||
}, EShortcut::GLOBAL_CANCEL);
|
||||
}
|
||||
|
||||
CLobbyScreen::~CLobbyScreen()
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
|
||||
@ -39,8 +40,7 @@ CSavingScreen::CSavingScreen()
|
||||
tabSel->toggleMode();
|
||||
|
||||
tabSel->callOnSelect = std::bind(&CSavingScreen::changeSelection, this, _1);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRSAV.DEF", CGI->generaltexth->zelp[103], std::bind(&CSavingScreen::saveGame, this), SDLK_s);
|
||||
buttonStart->assignedKeys.insert(SDLK_RETURN);
|
||||
buttonStart = std::make_shared<CButton>(Point(411, 535), "SCNRSAV.DEF", CGI->generaltexth->zelp[103], std::bind(&CSavingScreen::saveGame, this), EShortcut::LOBBY_SAVE_GAME);
|
||||
}
|
||||
|
||||
const CMapInfo * CSavingScreen::getMapInfo()
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -43,7 +44,7 @@ CScenarioInfoScreen::CScenarioInfoScreen()
|
||||
card->changeSelection();
|
||||
|
||||
card->iconDifficulty->setSelected(getCurrentDifficulty());
|
||||
buttonBack = std::make_shared<CButton>(Point(584, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, SDLK_ESCAPE);
|
||||
buttonBack = std::make_shared<CButton>(Point(584, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
}
|
||||
|
||||
CScenarioInfoScreen::~CScenarioInfoScreen()
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CServerHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../mainmenu/CMainMenu.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
@ -84,7 +85,7 @@ CSelectionBase::CSelectionBase(ESelectionScreen type)
|
||||
}
|
||||
pos = background->center();
|
||||
card = std::make_shared<InfoCard>();
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, SDLK_ESCAPE);
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
}
|
||||
|
||||
void CSelectionBase::toggleTab(std::shared_ptr<CIntObject> tab)
|
||||
@ -318,9 +319,9 @@ CChatBox::CChatBox(const Rect & rect)
|
||||
chatHistory->label->color = Colors::GREEN;
|
||||
}
|
||||
|
||||
void CChatBox::keyPressed(const SDL_Keycode & key)
|
||||
void CChatBox::keyPressed(EShortcut key)
|
||||
{
|
||||
if(key == SDLK_RETURN && inputBox->getText().size())
|
||||
if(key == EShortcut::GLOBAL_ACCEPT && inputBox->getText().size())
|
||||
{
|
||||
CSH->sendMessage(inputBox->getText());
|
||||
inputBox->setText("");
|
||||
|
@ -120,7 +120,7 @@ public:
|
||||
|
||||
CChatBox(const Rect & rect);
|
||||
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
void addNewMessage(const std::string & text);
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CServerHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
@ -281,27 +282,27 @@ void SelectionTab::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionTab::keyPressed(const SDL_Keycode & key)
|
||||
void SelectionTab::keyPressed(EShortcut key)
|
||||
{
|
||||
int moveBy = 0;
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_UP:
|
||||
case EShortcut::MOVE_UP:
|
||||
moveBy = -1;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
case EShortcut::MOVE_DOWN:
|
||||
moveBy = +1;
|
||||
break;
|
||||
case SDLK_PAGEUP:
|
||||
case EShortcut::MOVE_PAGE_UP:
|
||||
moveBy = -(int)listItems.size() + 1;
|
||||
break;
|
||||
case SDLK_PAGEDOWN:
|
||||
case EShortcut::MOVE_PAGE_DOWN:
|
||||
moveBy = +(int)listItems.size() - 1;
|
||||
break;
|
||||
case SDLK_HOME:
|
||||
case EShortcut::MOVE_FIRST:
|
||||
select(-slider->getValue());
|
||||
return;
|
||||
case SDLK_END:
|
||||
case EShortcut::MOVE_LAST:
|
||||
select((int)curItems.size() - slider->getValue());
|
||||
return;
|
||||
default:
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
void toggleMode();
|
||||
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
|
||||
void onDoubleClick() override;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CServerHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
@ -77,7 +78,7 @@ std::shared_ptr<CButton> CCampaignScreen::createExitButton(const JsonNode & butt
|
||||
if(!button["help"].isNull() && button["help"].Float() > 0)
|
||||
help = CGI->generaltexth->zelp[(size_t)button["help"].Float()];
|
||||
|
||||
return std::make_shared<CButton>(Point((int)button["x"].Float(), (int)button["y"].Float()), button["name"].String(), help, [=](){ close();}, (int)button["hotkey"].Float());
|
||||
return std::make_shared<CButton>(Point((int)button["x"].Float(), (int)button["y"].Float()), button["name"].String(), help, [=](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
}
|
||||
|
||||
CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config)
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/ShortcutHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
@ -230,7 +232,9 @@ std::shared_ptr<CButton> CMenuEntry::createButton(CMenuScreen * parent, const Js
|
||||
if(posy < 0)
|
||||
posy = pos.h + posy;
|
||||
|
||||
auto result = std::make_shared<CButton>(Point(posx, posy), button["name"].String(), help, command, (int)button["hotkey"].Float());
|
||||
EShortcut shortcut = GH.shortcutsHandler().findShortcut(button["shortcut"].String());
|
||||
|
||||
auto result = std::make_shared<CButton>(Point(posx, posy), button["name"].String(), help, command, shortcut);
|
||||
|
||||
if (button["center"].Bool())
|
||||
result->moveBy(Point(-result->pos.w/2, -result->pos.h/2));
|
||||
@ -382,7 +386,7 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
|
||||
buttonHotseat = std::make_shared<CButton>(Point(373, 78), "MUBHOT.DEF", CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this));
|
||||
buttonHost = std::make_shared<CButton>(Point(373, 78 + 57 * 1), "MUBHOST.DEF", CButton::tooltip("Host TCP/IP game", ""), std::bind(&CMultiMode::hostTCP, this));
|
||||
buttonJoin = std::make_shared<CButton>(Point(373, 78 + 57 * 2), "MUBJOIN.DEF", CButton::tooltip("Join TCP/IP game", ""), std::bind(&CMultiMode::joinTCP, this));
|
||||
buttonCancel = std::make_shared<CButton>(Point(373, 424), "MUBCANC.DEF", CGI->generaltexth->zelp[288], [=](){ close();}, SDLK_ESCAPE);
|
||||
buttonCancel = std::make_shared<CButton>(Point(373, 424), "MUBCANC.DEF", CGI->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
}
|
||||
|
||||
void CMultiMode::hostTCP()
|
||||
@ -422,8 +426,8 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S
|
||||
inputNames[i]->cb += std::bind(&CMultiPlayers::onChange, this, _1);
|
||||
}
|
||||
|
||||
buttonOk = std::make_shared<CButton>(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), SDLK_RETURN);
|
||||
buttonCancel = std::make_shared<CButton>(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [=](){ close();}, SDLK_ESCAPE);
|
||||
buttonOk = std::make_shared<CButton>(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), EShortcut::GLOBAL_ACCEPT);
|
||||
buttonCancel = std::make_shared<CButton>(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(7, 381, 348, 18), 7, 381));
|
||||
|
||||
inputNames[0]->setText(firstPlayer, true);
|
||||
@ -471,14 +475,14 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
|
||||
inputAddress->cb += std::bind(&CSimpleJoinScreen::onChange, this, _1);
|
||||
inputPort->cb += std::bind(&CSimpleJoinScreen::onChange, this, _1);
|
||||
inputPort->filters += std::bind(&CTextInput::numberFilter, _1, _2, 0, 65535);
|
||||
buttonOk = std::make_shared<CButton>(Point(26, 142), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CSimpleJoinScreen::connectToServer, this), SDLK_RETURN);
|
||||
buttonOk = std::make_shared<CButton>(Point(26, 142), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CSimpleJoinScreen::connectToServer, this), EShortcut::GLOBAL_ACCEPT);
|
||||
|
||||
inputAddress->giveFocus();
|
||||
}
|
||||
inputAddress->setText(host ? CServerHandler::localhostAddress : CSH->getHostAddress(), true);
|
||||
inputPort->setText(std::to_string(CSH->getHostPort()), true);
|
||||
|
||||
buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE);
|
||||
buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), EShortcut::GLOBAL_CANCEL);
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(7, 186, 218, 18), 7, 186));
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CBitmapFont;
|
||||
|
||||
typedef struct _TTF_Font TTF_Font;
|
||||
using TTF_Font = struct _TTF_Font;
|
||||
|
||||
class CTrueTypeFont : public IFont
|
||||
{
|
||||
|
@ -45,8 +45,8 @@ SDL_Color toSDL(const ColorRGBA & color);
|
||||
void setColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);
|
||||
void setAlpha(SDL_Surface * bg, int value);
|
||||
|
||||
typedef void (*TColorPutter)(uint8_t *&ptr, const uint8_t & R, const uint8_t & G, const uint8_t & B);
|
||||
typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_t & G, const uint8_t & B, const uint8_t & A);
|
||||
using TColorPutter = void (*)(uint8_t *&, const uint8_t &, const uint8_t &, const uint8_t &);
|
||||
using TColorPutterAlpha = void (*)(uint8_t *&, const uint8_t &, const uint8_t &, const uint8_t &, const uint8_t &);
|
||||
|
||||
void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst);
|
||||
void blitAt(SDL_Surface * src, const Rect & pos, SDL_Surface * dst);
|
||||
@ -57,23 +57,23 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
void blitSurface(SDL_Surface * src, const Rect & srcRect, SDL_Surface * dst, const Point & dest);
|
||||
void blitSurface(SDL_Surface * src, SDL_Surface * dst, const Point & dest);
|
||||
|
||||
void fillSurface(SDL_Surface *dst, const SDL_Color & color);
|
||||
void fillRect(SDL_Surface *dst, const Rect & dstrect, const SDL_Color & color);
|
||||
void fillSurface(SDL_Surface * dst, const SDL_Color & color);
|
||||
void fillRect(SDL_Surface * dst, const Rect & dstrect, const SDL_Color & color);
|
||||
|
||||
void updateRect(SDL_Surface *surface, const Rect & rect);
|
||||
void updateRect(SDL_Surface * surface, const Rect & rect);
|
||||
|
||||
void putPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const uint8_t & R, const uint8_t & G, const uint8_t & B, uint8_t A = 255);
|
||||
void putPixelWithoutRefresh(SDL_Surface * ekran, const int & x, const int & y, const uint8_t & R, const uint8_t & G, const uint8_t & B, uint8_t A = 255);
|
||||
void putPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x, const int & y, const uint8_t & R, const uint8_t & G, const uint8_t & B, uint8_t A = 255);
|
||||
|
||||
SDL_Surface * verticalFlip(SDL_Surface * toRot); //vertical flip
|
||||
SDL_Surface * horizontalFlip(SDL_Surface * toRot); //horizontal flip
|
||||
uint32_t getPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte = false);
|
||||
uint32_t getPixel(SDL_Surface * surface, const int & x, const int & y, bool colorByte = false);
|
||||
bool isTransparent(SDL_Surface * srf, int x, int y); //checks if surface is transparent at given position
|
||||
bool isTransparent(SDL_Surface * srf, const Point & position); //checks if surface is transparent at given position
|
||||
bool isTransparent(SDL_Surface * srf, const Point & position); //checks if surface is transparent at given position
|
||||
|
||||
uint8_t *getPxPtr(const SDL_Surface * const &srf, const int x, const int y);
|
||||
TColorPutter getPutterFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1
|
||||
TColorPutterAlpha getPutterAlphaFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1
|
||||
uint8_t * getPxPtr(const SDL_Surface * const & srf, const int x, const int y);
|
||||
TColorPutter getPutterFor(SDL_Surface * const & dest, int incrementing); //incrementing: -1, 0, 1
|
||||
TColorPutterAlpha getPutterAlphaFor(SDL_Surface * const & dest, int incrementing); //incrementing: -1, 0, 1
|
||||
|
||||
template<int bpp>
|
||||
int blit8bppAlphaTo24bppT(const SDL_Surface * src, const Rect & srcRect, SDL_Surface * dst, const Point & dstPoint); //blits 8 bpp surface with alpha channel to 24 bpp surface
|
||||
@ -84,8 +84,8 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
void drawLine(SDL_Surface * sur, const Point & from, const Point & dest, const SDL_Color & color1, const SDL_Color & color2);
|
||||
void drawLineDashed(SDL_Surface * sur, const Point & from, const Point & dest, const SDL_Color & color);
|
||||
|
||||
void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color &color, int depth = 1);
|
||||
void drawBorder(SDL_Surface * sur, const Rect &r, const SDL_Color &color, int depth = 1);
|
||||
void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color & color, int depth = 1);
|
||||
void drawBorder(SDL_Surface * sur, const Rect & r, const SDL_Color & color, int depth = 1);
|
||||
void setPlayerColor(SDL_Surface * sur, PlayerColor player); //sets correct color of flags; -1 for neutral
|
||||
|
||||
SDL_Surface * newSurface(int w, int h, SDL_Surface * mod); //creates new surface, with flags/format same as in surface given
|
||||
@ -97,18 +97,18 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
|
||||
//scale surface to required size.
|
||||
//nearest neighbour algorithm
|
||||
SDL_Surface * scaleSurfaceFast(SDL_Surface *surf, int width, int height);
|
||||
SDL_Surface * scaleSurfaceFast(SDL_Surface * surf, int width, int height);
|
||||
// bilinear filtering. Uses fallback to scaleSurfaceFast in case of indexed surfaces
|
||||
SDL_Surface * scaleSurface(SDL_Surface *surf, int width, int height);
|
||||
SDL_Surface * scaleSurface(SDL_Surface * surf, int width, int height);
|
||||
|
||||
template<int bpp>
|
||||
void convertToGrayscaleBpp( SDL_Surface * surf, const Rect & rect );
|
||||
void convertToGrayscaleBpp(SDL_Surface * surf, const Rect & rect);
|
||||
void convertToGrayscale(SDL_Surface * surf, const Rect & rect);
|
||||
|
||||
bool isResolutionSupported(const std::vector<Point> & resolutions, const Point toTest );
|
||||
bool isResolutionSupported(const std::vector<Point> & resolutions, const Point toTest);
|
||||
|
||||
std::vector<Point> getSupportedResolutions();
|
||||
std::vector<Point> getSupportedResolutions( int displayIndex);
|
||||
std::vector<Point> getSupportedResolutions(int displayIndex);
|
||||
|
||||
void setColorKey(SDL_Surface * surface, SDL_Color color);
|
||||
|
||||
@ -118,13 +118,13 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
void setDefaultColorKeyPresize(SDL_Surface * surface);
|
||||
|
||||
/// helper that will safely set and un-set ClipRect for SDL_Surface
|
||||
class CClipRectGuard : boost::noncopyable
|
||||
class CClipRectGuard: boost::noncopyable
|
||||
{
|
||||
SDL_Surface * surf;
|
||||
Rect oldRect;
|
||||
|
||||
public:
|
||||
CClipRectGuard(SDL_Surface * surface, const Rect & rect):
|
||||
surf(surface)
|
||||
CClipRectGuard(SDL_Surface * surface, const Rect & rect): surf(surface)
|
||||
{
|
||||
CSDL_Ext::getClipRect(surf, oldRect);
|
||||
CSDL_Ext::setClipRect(surf, rect);
|
||||
|
@ -47,7 +47,7 @@ namespace Channels
|
||||
|
||||
static void STRONG_INLINE set(uint8_t *ptr, uint8_t value)
|
||||
{
|
||||
uint16_t * const pixel = (uint16_t*)ptr;
|
||||
auto * const pixel = (uint16_t *)ptr;
|
||||
uint8_t subpx = value >> (8 - bits);
|
||||
*pixel = (*pixel & ~mask) | ((subpx << shift) & mask );
|
||||
}
|
||||
@ -226,7 +226,7 @@ STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColor(uint8_t *&ptr, const u
|
||||
if(incrementPtr == -1)
|
||||
ptr -= 2;
|
||||
|
||||
uint16_t * const px = (uint16_t*)ptr;
|
||||
auto * const px = (uint16_t *)ptr;
|
||||
*px = (B>>3) + ((G>>2) << 5) + ((R>>3) << 11); //drop least significant bits of 24 bpp encoded color
|
||||
|
||||
if(incrementPtr == 1)
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../battle/BattleInterface.h"
|
||||
#include "../battle/BattleInterfaceClasses.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
@ -223,7 +224,7 @@ void CButton::hover (bool on)
|
||||
}
|
||||
}
|
||||
|
||||
CButton::CButton(Point position, const std::string &defName, const std::pair<std::string, std::string> &help, CFunctionList<void()> Callback, int key, bool playerColoredButton):
|
||||
CButton::CButton(Point position, const std::string &defName, const std::pair<std::string, std::string> &help, CFunctionList<void()> Callback, EShortcut key, bool playerColoredButton):
|
||||
CKeyShortcut(key),
|
||||
callback(Callback)
|
||||
{
|
||||
@ -345,7 +346,7 @@ void CToggleBase::addCallback(std::function<void(bool)> function)
|
||||
}
|
||||
|
||||
CToggleButton::CToggleButton(Point position, const std::string &defName, const std::pair<std::string, std::string> &help,
|
||||
CFunctionList<void(bool)> callback, int key, bool playerColoredButton):
|
||||
CFunctionList<void(bool)> callback, EShortcut key, bool playerColoredButton):
|
||||
CButton(position, defName, help, 0, key, playerColoredButton),
|
||||
CToggleBase(callback)
|
||||
{
|
||||
@ -800,37 +801,37 @@ void CSlider::wheelScrolled(bool down, bool in)
|
||||
moveTo(value + 3 * (positive ? +scrollStep : -scrollStep));
|
||||
}
|
||||
|
||||
void CSlider::keyPressed(const SDL_Keycode & key)
|
||||
void CSlider::keyPressed(EShortcut key)
|
||||
{
|
||||
int moveDest = value;
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_UP:
|
||||
case EShortcut::MOVE_UP:
|
||||
if (!horizontal)
|
||||
moveDest = value - scrollStep;
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
case EShortcut::MOVE_LEFT:
|
||||
if (horizontal)
|
||||
moveDest = value - scrollStep;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
case EShortcut::MOVE_DOWN:
|
||||
if (!horizontal)
|
||||
moveDest = value + scrollStep;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
case EShortcut::MOVE_RIGHT:
|
||||
if (horizontal)
|
||||
moveDest = value + scrollStep;
|
||||
break;
|
||||
case SDLK_PAGEUP:
|
||||
case EShortcut::MOVE_PAGE_UP:
|
||||
moveDest = value - capacity + scrollStep;
|
||||
break;
|
||||
case SDLK_PAGEDOWN:
|
||||
case EShortcut::MOVE_PAGE_DOWN:
|
||||
moveDest = value + capacity - scrollStep;
|
||||
break;
|
||||
case SDLK_HOME:
|
||||
case EShortcut::MOVE_FIRST:
|
||||
moveDest = 0;
|
||||
break;
|
||||
case SDLK_END:
|
||||
case EShortcut::MOVE_LAST:
|
||||
moveDest = amount - capacity;
|
||||
break;
|
||||
default:
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
|
||||
/// Constructor
|
||||
CButton(Point position, const std::string & defName, const std::pair<std::string, std::string> & help,
|
||||
CFunctionList<void()> Callback = 0, int key=0, bool playerColoredButton = false );
|
||||
CFunctionList<void()> Callback = 0, EShortcut key = {}, bool playerColoredButton = false );
|
||||
|
||||
/// Appearance modifiers
|
||||
void setIndex(size_t index, bool playerColoredButton=false);
|
||||
@ -157,7 +157,7 @@ class CToggleButton : public CButton, public CToggleBase
|
||||
|
||||
public:
|
||||
CToggleButton(Point position, const std::string &defName, const std::pair<std::string, std::string> &help,
|
||||
CFunctionList<void(bool)> Callback = 0, int key=0, bool playerColoredButton = false );
|
||||
CFunctionList<void(bool)> Callback = 0, EShortcut key = {}, bool playerColoredButton = false );
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
|
||||
// bring overrides into scope
|
||||
@ -276,7 +276,7 @@ public:
|
||||
|
||||
void addCallback(std::function<void(int)> callback);
|
||||
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
void wheelScrolled(bool down, bool in) override;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void mouseMoved (const Point & cursorPosition) override;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,37 +14,38 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct ArtifactLocation;
|
||||
class CArtifactSet;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CArtifactsOfHero;
|
||||
class CAnimImage;
|
||||
class CButton;
|
||||
|
||||
class CArtifactHolder
|
||||
{
|
||||
public:
|
||||
CArtifactHolder();
|
||||
|
||||
virtual void artifactRemoved(const ArtifactLocation &artLoc)=0;
|
||||
virtual void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc, bool withRedraw)=0;
|
||||
virtual void artifactDisassembled(const ArtifactLocation &artLoc)=0;
|
||||
virtual void artifactAssembled(const ArtifactLocation &artLoc)=0;
|
||||
virtual void artifactRemoved(const ArtifactLocation & artLoc)=0;
|
||||
virtual void artifactMoved(const ArtifactLocation & artLoc, const ArtifactLocation & destLoc, bool withRedraw)=0;
|
||||
virtual void artifactDisassembled(const ArtifactLocation & artLoc)=0;
|
||||
virtual void artifactAssembled(const ArtifactLocation & artLoc)=0;
|
||||
};
|
||||
|
||||
class CArtPlace : public LRClickableAreaWTextComp
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<CAnimImage> image;
|
||||
virtual void createImage()=0;
|
||||
public:
|
||||
const CArtifactInstance * ourArt; // should be changed only with setArtifact()
|
||||
const CArtifactInstance * ourArt;
|
||||
|
||||
void setInternals(const CArtifactInstance * artInst);
|
||||
virtual void createImage()=0;
|
||||
|
||||
public:
|
||||
CArtPlace(Point position, const CArtifactInstance * Art = nullptr);
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
const CArtifactInstance * getArt();
|
||||
|
||||
virtual void setArtifact(const CArtifactInstance *art)=0;
|
||||
virtual void setArtifact(const CArtifactInstance * art)=0;
|
||||
};
|
||||
|
||||
class CCommanderArtPlace : public CArtPlace
|
||||
@ -55,138 +56,44 @@ protected:
|
||||
|
||||
void createImage() override;
|
||||
void returnArtToHeroCallback();
|
||||
|
||||
public:
|
||||
CCommanderArtPlace(Point position, const CGHeroInstance * commanderOwner, ArtifactPosition artSlot, const CArtifactInstance * Art = nullptr);
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
|
||||
virtual void setArtifact(const CArtifactInstance * art) override;
|
||||
|
||||
void setArtifact(const CArtifactInstance * art) override;
|
||||
};
|
||||
|
||||
/// Artifacts can be placed there. Gets shown at the hero window
|
||||
class CHeroArtPlace: public CArtPlace
|
||||
{
|
||||
std::shared_ptr<CAnimImage> selection;
|
||||
|
||||
void createImage() override;
|
||||
|
||||
public:
|
||||
// consider these members as const - change them only with appropriate methods e.g. lockSlot()
|
||||
bool locked;
|
||||
bool picked;
|
||||
bool marked;
|
||||
using ClickHandler = std::function<void(CHeroArtPlace&)>;
|
||||
|
||||
ArtifactPosition slotID; //Arts::EPOS enum + backpack starting from Arts::BACKPACK_START
|
||||
|
||||
CArtifactsOfHero * ourOwner;
|
||||
ArtifactPosition slot;
|
||||
ClickHandler leftClickCallback;
|
||||
ClickHandler rightClickCallback;
|
||||
|
||||
CHeroArtPlace(Point position, const CArtifactInstance * Art = nullptr);
|
||||
|
||||
void lockSlot(bool on);
|
||||
void pickSlot(bool on);
|
||||
bool isLocked();
|
||||
void selectSlot(bool on);
|
||||
|
||||
bool isMarked() const;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
void select();
|
||||
void showAll(SDL_Surface * to) override;
|
||||
bool fitsHere (const CArtifactInstance * art) const; //returns true if given artifact can be placed here
|
||||
void setArtifact(const CArtifactInstance * art) override;
|
||||
void addCombinedArtInfo(std::map<const CArtifact*, int> & arts);
|
||||
|
||||
void setMeAsDest(bool backpackAsVoid = true);
|
||||
void setArtifact(const CArtifactInstance *art) override;
|
||||
static bool askToAssemble(const CGHeroInstance * hero, ArtifactPosition slot);
|
||||
static bool askToDisassemble(const CGHeroInstance * hero, ArtifactPosition slot);
|
||||
protected:
|
||||
std::shared_ptr<CAnimImage> selection;
|
||||
bool locked;
|
||||
bool marked;
|
||||
|
||||
void createImage() override;
|
||||
};
|
||||
|
||||
/// Contains artifacts of hero. Distincts which artifacts are worn or backpacked
|
||||
class CArtifactsOfHero : public CIntObject
|
||||
namespace ArtifactUtilsClient
|
||||
{
|
||||
public:
|
||||
using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>;
|
||||
using ArtPlaceMap = std::map<ArtifactPosition, ArtPlacePtr>;
|
||||
|
||||
struct SCommonPart
|
||||
{
|
||||
struct Artpos
|
||||
{
|
||||
ArtifactPosition slotID;
|
||||
const CArtifactsOfHero *AOH;
|
||||
const CArtifactInstance *art;
|
||||
|
||||
void clear();
|
||||
void setTo(const CHeroArtPlace *place, bool dontTakeBackpack);
|
||||
bool valid();
|
||||
bool operator==(const ArtifactLocation &al) const;
|
||||
} src, dst;
|
||||
|
||||
std::set<CArtifactsOfHero *> participants; // Needed to mark slots.
|
||||
|
||||
void reset();
|
||||
};
|
||||
std::shared_ptr<SCommonPart> commonInfo; //when we have more than one CArtifactsOfHero in one window with exchange possibility, we use this (eg. in exchange window); to be provided externally
|
||||
|
||||
std::shared_ptr<CButton> leftArtRoll;
|
||||
std::shared_ptr<CButton> rightArtRoll;
|
||||
bool allowedAssembling;
|
||||
|
||||
std::multiset<const CArtifactInstance*> artifactsOnAltar; //artifacts id that are technically present in backpack but in GUI are moved to the altar - they'll be omitted in backpack slots
|
||||
std::function<void(CHeroArtPlace*)> highlightModeCallback; //if set, clicking on art place doesn't pick artifact but highlights the slot and calls this function
|
||||
|
||||
void realizeCurrentTransaction(); //calls callback with parameters stored in commonInfo
|
||||
void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst, bool withUIUpdate);
|
||||
void artifactRemoved(const ArtifactLocation &al);
|
||||
void artifactUpdateSlots(const ArtifactLocation &al);
|
||||
ArtPlacePtr getArtPlace(ArtifactPosition slot);//may return null
|
||||
|
||||
void setHero(const CGHeroInstance * hero);
|
||||
const CGHeroInstance *getHero() const;
|
||||
void dispose(); //free resources not needed after closing windows and reset state
|
||||
void scrollBackpack(int dir); //dir==-1 => to left; dir==1 => to right
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
void safeRedraw();
|
||||
void markPossibleSlots(const CArtifactInstance * art, bool withRedraw = false);
|
||||
void unmarkSlots(bool withRedraw = false); //unmarks slots in all visible AOHs
|
||||
void unmarkLocalSlots(bool withRedraw = false); //unmarks slots in that particular AOH
|
||||
void updateWornSlots(bool redrawParent = false);
|
||||
void updateBackpackSlots(bool redrawParent = false);
|
||||
|
||||
void updateSlot(ArtifactPosition i);
|
||||
|
||||
CArtifactsOfHero(const Point& position, bool createCommonPart = false);
|
||||
//Alternative constructor, used if custom artifacts positioning required (Kingdom interface)
|
||||
CArtifactsOfHero(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
|
||||
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll, bool createCommonPart = false);
|
||||
~CArtifactsOfHero();
|
||||
void updateParentWindow();
|
||||
friend class CHeroArtPlace;
|
||||
|
||||
private:
|
||||
|
||||
const CGHeroInstance * curHero;
|
||||
|
||||
ArtPlaceMap artWorn;
|
||||
|
||||
std::vector<ArtPlacePtr> backpack; //hero's visible backpack (only 5 elements!)
|
||||
int backpackPos; //number of first art visible in backpack (in hero's vector)
|
||||
|
||||
void eraseSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID);
|
||||
void setSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID);
|
||||
};
|
||||
|
||||
class CWindowWithArtifacts : public CArtifactHolder
|
||||
{
|
||||
std::vector<std::weak_ptr<CArtifactsOfHero>> artSets;
|
||||
public:
|
||||
void addSet(std::shared_ptr<CArtifactsOfHero> artSet);
|
||||
|
||||
std::shared_ptr<CArtifactsOfHero::SCommonPart> getCommonPart();
|
||||
|
||||
void artifactRemoved(const ArtifactLocation &artLoc) override;
|
||||
void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc, bool withRedraw) override;
|
||||
void artifactDisassembled(const ArtifactLocation &artLoc) override;
|
||||
void artifactAssembled(const ArtifactLocation &artLoc) override;
|
||||
};
|
||||
bool askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot);
|
||||
bool askToDisassemble(const CGHeroInstance * hero, const ArtifactPosition & slot);
|
||||
}
|
||||
|
109
client/widgets/CArtifactsOfHeroAltar.cpp
Normal file
109
client/widgets/CArtifactsOfHeroAltar.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* CArtifactsOfHeroAltar.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsOfHeroAltar.h"
|
||||
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CArtifactsOfHeroAltar::CArtifactsOfHeroAltar(const Point & position)
|
||||
: visibleArtSet(ArtBearer::ArtBearer::HERO)
|
||||
{
|
||||
init(
|
||||
std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1),
|
||||
std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1),
|
||||
position,
|
||||
std::bind(&CArtifactsOfHeroAltar::scrollBackpack, this, _1));
|
||||
pickedArtFromSlot = ArtifactPosition::PRE_FIRST;
|
||||
};
|
||||
|
||||
void CArtifactsOfHeroAltar::setHero(const CGHeroInstance * hero)
|
||||
{
|
||||
if(hero)
|
||||
{
|
||||
visibleArtSet.artifactsWorn = hero->artifactsWorn;
|
||||
visibleArtSet.artifactsInBackpack = hero->artifactsInBackpack;
|
||||
CArtifactsOfHeroBase::setHero(hero);
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::updateWornSlots()
|
||||
{
|
||||
for(auto place : artWorn)
|
||||
setSlotData(getArtPlace(place.first), place.first, visibleArtSet);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::updateBackpackSlots()
|
||||
{
|
||||
for(auto artPlace : backpack)
|
||||
setSlotData(getArtPlace(artPlace->slot), artPlace->slot, visibleArtSet);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::scrollBackpack(int offset)
|
||||
{
|
||||
CArtifactsOfHeroBase::scrollBackpackForArtSet(offset, visibleArtSet);
|
||||
safeRedraw();
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::pickUpArtifact(CHeroArtPlace & artPlace)
|
||||
{
|
||||
if(const auto art = artPlace.getArt())
|
||||
{
|
||||
pickedArtFromSlot = artPlace.slot;
|
||||
artPlace.setArtifact(nullptr);
|
||||
deleteFromVisible(art);
|
||||
if(ArtifactUtils::isSlotBackpack(pickedArtFromSlot))
|
||||
pickedArtFromSlot = curHero->getSlotByInstance(art);
|
||||
assert(pickedArtFromSlot != ArtifactPosition::PRE_FIRST);
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, pickedArtFromSlot), ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS));
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc)
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
||||
const auto pickedArtInst = curHero->getArt(ArtifactPosition::TRANSITION_POS);
|
||||
assert(pickedArtInst);
|
||||
visibleArtSet.putArtifact(dstLoc.slot, const_cast<CArtifactInstance*>(pickedArtInst));
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::pickedArtMoveToAltar(const ArtifactPosition & slot)
|
||||
{
|
||||
if(ArtifactUtils::isSlotBackpack(slot) || ArtifactUtils::isSlotEquipment(slot) || slot == ArtifactPosition::TRANSITION_POS)
|
||||
{
|
||||
assert(!curHero->getSlot(pickedArtFromSlot)->getArt());
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, slot), ArtifactLocation(curHero, pickedArtFromSlot));
|
||||
pickedArtFromSlot = ArtifactPosition::PRE_FIRST;
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroAltar::deleteFromVisible(const CArtifactInstance * artInst)
|
||||
{
|
||||
const auto slot = visibleArtSet.getSlotByInstance(artInst);
|
||||
visibleArtSet.removeArtifact(slot);
|
||||
if(ArtifactUtils::isSlotBackpack(slot))
|
||||
{
|
||||
scrollBackpackForArtSet(0, visibleArtSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(artInst->canBeDisassembled())
|
||||
{
|
||||
for(const auto & part : dynamic_cast<const CCombinedArtifactInstance*>(artInst)->constituentsInfo)
|
||||
{
|
||||
if(part.slot != ArtifactPosition::PRE_FIRST)
|
||||
getArtPlace(part.slot)->setArtifact(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
client/widgets/CArtifactsOfHeroAltar.h
Normal file
32
client/widgets/CArtifactsOfHeroAltar.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* CArtifactsOfHeroAltar.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CArtifactsOfHeroBase.h"
|
||||
|
||||
#include "../../lib/CArtHandler.h"
|
||||
|
||||
class CArtifactsOfHeroAltar : public CArtifactsOfHeroBase
|
||||
{
|
||||
public:
|
||||
std::set<const CArtifactInstance*> artifactsOnAltar;
|
||||
ArtifactPosition pickedArtFromSlot;
|
||||
CArtifactFittingSet visibleArtSet;
|
||||
|
||||
CArtifactsOfHeroAltar(const Point & position);
|
||||
void setHero(const CGHeroInstance * hero) override;
|
||||
void updateWornSlots() override;
|
||||
void updateBackpackSlots() override;
|
||||
void scrollBackpack(int offset) override;
|
||||
void pickUpArtifact(CHeroArtPlace & artPlace);
|
||||
void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc);
|
||||
void pickedArtMoveToAltar(const ArtifactPosition & slot);
|
||||
void deleteFromVisible(const CArtifactInstance * artInst);
|
||||
};
|
278
client/widgets/CArtifactsOfHeroBase.cpp
Normal file
278
client/widgets/CArtifactsOfHeroBase.cpp
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* CArtifactsOfHeroBase.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsOfHeroBase.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
|
||||
#include "Buttons.h"
|
||||
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CGameInfo.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CArtifactsOfHeroBase::CArtifactsOfHeroBase()
|
||||
: backpackPos(0),
|
||||
curHero(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CArtifactsOfHeroBase::~CArtifactsOfHeroBase()
|
||||
{
|
||||
// TODO: cursor handling is CWindowWithArtifacts level. Should be moved when trading, kingdom and hero window are reworked
|
||||
// This will interfere with the implementation of a separate backpack window
|
||||
CCS->curh->dragAndDropCursor(nullptr);
|
||||
|
||||
// Artifact located in artifactsTransitionPos should be returned
|
||||
if(getPickedArtifact())
|
||||
{
|
||||
auto slot = ArtifactUtils::getArtAnyPosition(curHero, curHero->artifactsTransitionPos.begin()->artifact->getTypeId());
|
||||
if(slot == ArtifactPosition::PRE_FIRST)
|
||||
{
|
||||
LOCPLINT->cb->eraseArtifactByClient(ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS), ArtifactLocation(curHero, slot));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::init(
|
||||
CHeroArtPlace::ClickHandler lClickCallback,
|
||||
CHeroArtPlace::ClickHandler rClickCallback,
|
||||
const Point & position,
|
||||
BpackScrollHandler scrollHandler)
|
||||
{
|
||||
// CArtifactsOfHeroBase::init may be transform to CArtifactsOfHeroBase::CArtifactsOfHeroBase if OBJECT_CONSTRUCTION_CAPTURING is removed
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
pos += position;
|
||||
for(int g = 0; g < GameConstants::BACKPACK_START; g++)
|
||||
{
|
||||
artWorn[ArtifactPosition(g)] = std::make_shared<CHeroArtPlace>(slotPos[g]);
|
||||
}
|
||||
backpack.clear();
|
||||
for(int s = 0; s < 5; s++)
|
||||
{
|
||||
auto artPlace = std::make_shared<CHeroArtPlace>(Point(403 + 46 * s, 365));
|
||||
backpack.push_back(artPlace);
|
||||
}
|
||||
for(auto artPlace : artWorn)
|
||||
{
|
||||
artPlace.second->slot = artPlace.first;
|
||||
artPlace.second->setArtifact(nullptr);
|
||||
artPlace.second->leftClickCallback = lClickCallback;
|
||||
artPlace.second->rightClickCallback = rClickCallback;
|
||||
}
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
artPlace->setArtifact(nullptr);
|
||||
artPlace->leftClickCallback = lClickCallback;
|
||||
artPlace->rightClickCallback = rClickCallback;
|
||||
}
|
||||
leftBackpackRoll = std::make_shared<CButton>(Point(379, 364), "hsbtns3.def", CButton::tooltip(), [scrollHandler]() { scrollHandler(-1); }, EShortcut::MOVE_LEFT);
|
||||
rightBackpackRoll = std::make_shared<CButton>(Point(632, 364), "hsbtns5.def", CButton::tooltip(), [scrollHandler]() { scrollHandler(+1); }, EShortcut::MOVE_RIGHT);
|
||||
leftBackpackRoll->block(true);
|
||||
rightBackpackRoll->block(true);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::leftClickArtPlace(CHeroArtPlace & artPlace)
|
||||
{
|
||||
if(leftClickCallback)
|
||||
leftClickCallback(*this, artPlace);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::rightClickArtPlace(CHeroArtPlace & artPlace)
|
||||
{
|
||||
if(rightClickCallback)
|
||||
rightClickCallback(*this, artPlace);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero)
|
||||
{
|
||||
curHero = hero;
|
||||
if(curHero->artifactsInBackpack.size() > 0)
|
||||
backpackPos %= curHero->artifactsInBackpack.size();
|
||||
else
|
||||
backpackPos = 0;
|
||||
|
||||
for(auto slot : artWorn)
|
||||
{
|
||||
setSlotData(slot.second, slot.first, *curHero);
|
||||
}
|
||||
scrollBackpackForArtSet(0, *curHero);
|
||||
}
|
||||
|
||||
const CGHeroInstance * CArtifactsOfHeroBase::getHero() const
|
||||
{
|
||||
return curHero;
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::scrollBackpack(int offset)
|
||||
{
|
||||
scrollBackpackForArtSet(offset, *curHero);
|
||||
safeRedraw();
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::scrollBackpackForArtSet(int offset, const CArtifactSet & artSet)
|
||||
{
|
||||
// offset==-1 => to left; offset==1 => to right
|
||||
using slotInc = std::function<ArtifactPosition(ArtifactPosition&)>;
|
||||
auto artsInBackpack = static_cast<int>(artSet.artifactsInBackpack.size());
|
||||
auto scrollingPossible = artsInBackpack > backpack.size();
|
||||
|
||||
slotInc inc_straight = [](ArtifactPosition & slot) -> ArtifactPosition
|
||||
{
|
||||
return slot + 1;
|
||||
};
|
||||
slotInc inc_ring = [artsInBackpack](ArtifactPosition & slot) -> ArtifactPosition
|
||||
{
|
||||
return ArtifactPosition(GameConstants::BACKPACK_START + (slot - GameConstants::BACKPACK_START + 1) % artsInBackpack);
|
||||
};
|
||||
slotInc inc;
|
||||
if(scrollingPossible)
|
||||
inc = inc_ring;
|
||||
else
|
||||
inc = inc_straight;
|
||||
|
||||
backpackPos += offset;
|
||||
if(backpackPos < 0)
|
||||
backpackPos += artsInBackpack;
|
||||
|
||||
if(artsInBackpack)
|
||||
backpackPos %= artsInBackpack;
|
||||
|
||||
auto slot = ArtifactPosition(GameConstants::BACKPACK_START + backpackPos);
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
setSlotData(artPlace, slot, artSet);
|
||||
slot = inc(slot);
|
||||
}
|
||||
|
||||
// Blocking scrolling if there is not enough artifacts to scroll
|
||||
leftBackpackRoll->block(!scrollingPossible);
|
||||
rightBackpackRoll->block(!scrollingPossible);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::safeRedraw()
|
||||
{
|
||||
if(active)
|
||||
{
|
||||
if(parent)
|
||||
parent->redraw();
|
||||
else
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved)
|
||||
{
|
||||
for(auto artPlace : artWorn)
|
||||
artPlace.second->selectSlot(art->artType->canBePutAt(curHero, artPlace.second->slot, assumeDestRemoved));
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::unmarkSlots()
|
||||
{
|
||||
for(auto & artPlace : artWorn)
|
||||
artPlace.second->selectSlot(false);
|
||||
|
||||
for(auto & artPlace : backpack)
|
||||
artPlace->selectSlot(false);
|
||||
}
|
||||
|
||||
CArtifactsOfHeroBase::ArtPlacePtr CArtifactsOfHeroBase::getArtPlace(const ArtifactPosition & slot)
|
||||
{
|
||||
if(ArtifactUtils::isSlotEquipment(slot))
|
||||
{
|
||||
if(artWorn.find(slot) == artWorn.end())
|
||||
{
|
||||
logGlobal->error("CArtifactsOfHero::getArtPlace: invalid slot %d", slot);
|
||||
return nullptr;
|
||||
}
|
||||
return artWorn[slot];
|
||||
}
|
||||
if(ArtifactUtils::isSlotBackpack(slot))
|
||||
{
|
||||
for(ArtPlacePtr artPlace : backpack)
|
||||
if(artPlace->slot == slot)
|
||||
return artPlace;
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::updateWornSlots()
|
||||
{
|
||||
for(auto place : artWorn)
|
||||
updateSlot(place.first);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::updateBackpackSlots()
|
||||
{
|
||||
for(auto artPlace : backpack)
|
||||
updateSlot(artPlace->slot);
|
||||
scrollBackpackForArtSet(0, *curHero);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::updateSlot(const ArtifactPosition & slot)
|
||||
{
|
||||
setSlotData(getArtPlace(slot), slot, *curHero);
|
||||
}
|
||||
|
||||
const CArtifactInstance * CArtifactsOfHeroBase::getPickedArtifact()
|
||||
{
|
||||
// Returns only the picked up artifact. Not just highlighted like in the trading window.
|
||||
if(!curHero || curHero->artifactsTransitionPos.empty())
|
||||
return nullptr;
|
||||
else
|
||||
return curHero->getArt(ArtifactPosition::TRANSITION_POS);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot, const CArtifactSet & artSet)
|
||||
{
|
||||
// Spurious call from artifactMoved in attempt to update hidden backpack slot
|
||||
if(!artPlace && ArtifactUtils::isSlotBackpack(slot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
artPlace->slot = slot;
|
||||
if(auto slotInfo = artSet.getSlot(slot))
|
||||
{
|
||||
artPlace->lockSlot(slotInfo->locked);
|
||||
artPlace->setArtifact(slotInfo->artifact);
|
||||
if(!slotInfo->artifact->canBeDisassembled())
|
||||
{
|
||||
// If the artifact is part of at least one combined artifact, add additional information
|
||||
std::map<const CArtifact*, int> arts;
|
||||
for(const auto combinedArt : slotInfo->artifact->artType->constituentOf)
|
||||
{
|
||||
arts.insert(std::pair(combinedArt, 0));
|
||||
for(const auto part : *combinedArt->constituents)
|
||||
if(artSet.hasArt(part->getId(), true))
|
||||
arts.at(combinedArt)++;
|
||||
}
|
||||
artPlace->addCombinedArtInfo(arts);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
artPlace->setArtifact(nullptr);
|
||||
}
|
||||
}
|
67
client/widgets/CArtifactsOfHeroBase.h
Normal file
67
client/widgets/CArtifactsOfHeroBase.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* CArtifactsOfHeroBase.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CArtifactHolder.h"
|
||||
|
||||
class CArtifactsOfHeroBase : public CIntObject
|
||||
{
|
||||
protected:
|
||||
using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>;
|
||||
using BpackScrollHandler = std::function<void(int)>;
|
||||
|
||||
public:
|
||||
using ArtPlaceMap = std::map<ArtifactPosition, ArtPlacePtr>;
|
||||
using ClickHandler = std::function<void(CArtifactsOfHeroBase&, CHeroArtPlace&)>;
|
||||
|
||||
const CGHeroInstance * curHero;
|
||||
ClickHandler leftClickCallback;
|
||||
ClickHandler rightClickCallback;
|
||||
|
||||
CArtifactsOfHeroBase();
|
||||
virtual ~CArtifactsOfHeroBase();
|
||||
virtual void leftClickArtPlace(CHeroArtPlace & artPlace);
|
||||
virtual void rightClickArtPlace(CHeroArtPlace & artPlace);
|
||||
virtual void setHero(const CGHeroInstance * hero);
|
||||
virtual const CGHeroInstance * getHero() const;
|
||||
virtual void scrollBackpack(int offset);
|
||||
virtual void safeRedraw();
|
||||
virtual void markPossibleSlots(const CArtifactInstance * art, bool assumeDestRemoved = true);
|
||||
virtual void unmarkSlots();
|
||||
virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot);
|
||||
virtual void updateWornSlots();
|
||||
virtual void updateBackpackSlots();
|
||||
virtual void updateSlot(const ArtifactPosition & slot);
|
||||
virtual const CArtifactInstance * getPickedArtifact();
|
||||
|
||||
protected:
|
||||
ArtPlaceMap artWorn;
|
||||
std::vector<ArtPlacePtr> backpack;
|
||||
std::shared_ptr<CButton> leftBackpackRoll;
|
||||
std::shared_ptr<CButton> rightBackpackRoll;
|
||||
int backpackPos; // Position to display artifacts in heroes backpack
|
||||
|
||||
const std::vector<Point> slotPos =
|
||||
{
|
||||
Point(509,30), Point(567,240), Point(509,80), //0-2
|
||||
Point(383,68), Point(564,183), Point(509,130), //3-5
|
||||
Point(431,68), Point(610,183), Point(515,295), //6-8
|
||||
Point(383,143), Point(399,194), Point(415,245), //9-11
|
||||
Point(431,296), Point(564,30), Point(610,30), //12-14
|
||||
Point(610,76), Point(610,122), Point(610,310), //15-17
|
||||
Point(381,296) //18
|
||||
};
|
||||
|
||||
virtual void init(CHeroArtPlace::ClickHandler lClickCallback, CHeroArtPlace::ClickHandler rClickCallback,
|
||||
const Point & position, BpackScrollHandler scrollHandler);
|
||||
// Assigns an artifacts to an artifact place depending on it's new slot ID
|
||||
virtual void setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot, const CArtifactSet & artSet);
|
||||
virtual void scrollBackpackForArtSet(int offset, const CArtifactSet & artSet);
|
||||
};
|
54
client/widgets/CArtifactsOfHeroKingdom.cpp
Normal file
54
client/widgets/CArtifactsOfHeroKingdom.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* CArtifactsOfHeroKingdom.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsOfHeroKingdom.h"
|
||||
|
||||
#include "Buttons.h"
|
||||
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
CArtifactsOfHeroKingdom::CArtifactsOfHeroKingdom(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
|
||||
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll)
|
||||
{
|
||||
artWorn = ArtWorn;
|
||||
backpack = Backpack;
|
||||
leftBackpackRoll = leftScroll;
|
||||
rightBackpackRoll = rightScroll;
|
||||
|
||||
for(auto artPlace : artWorn)
|
||||
{
|
||||
artPlace.second->slot = artPlace.first;
|
||||
artPlace.second->setArtifact(nullptr);
|
||||
artPlace.second->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1);
|
||||
artPlace.second->rightClickCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1);
|
||||
}
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
artPlace->setArtifact(nullptr);
|
||||
artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1);
|
||||
artPlace->rightClickCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1);
|
||||
}
|
||||
leftBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, -1));
|
||||
rightBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, +1));
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroKingdom::swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc)
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroKingdom::pickUpArtifact(CHeroArtPlace & artPlace)
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, artPlace.slot),
|
||||
ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS));
|
||||
}
|
||||
|
27
client/widgets/CArtifactsOfHeroKingdom.h
Normal file
27
client/widgets/CArtifactsOfHeroKingdom.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* CArtifactsOfHeroKingdom.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CArtifactsOfHeroBase.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct ArtifactLocation;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CArtifactsOfHeroKingdom : public CArtifactsOfHeroBase
|
||||
{
|
||||
public:
|
||||
CArtifactsOfHeroKingdom(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
|
||||
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll);
|
||||
void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc);
|
||||
void pickUpArtifact(CHeroArtPlace & artPlace);
|
||||
};
|
35
client/widgets/CArtifactsOfHeroMain.cpp
Normal file
35
client/widgets/CArtifactsOfHeroMain.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* CArtifactsOfHeroMain.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsOfHeroMain.h"
|
||||
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position)
|
||||
{
|
||||
init(
|
||||
std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1),
|
||||
std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1),
|
||||
position,
|
||||
std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1));
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroMain::swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc)
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc);
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroMain::pickUpArtifact(CHeroArtPlace & artPlace)
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero, artPlace.slot),
|
||||
ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS));
|
||||
}
|
26
client/widgets/CArtifactsOfHeroMain.h
Normal file
26
client/widgets/CArtifactsOfHeroMain.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* CArtifactsOfHeroMain.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CArtifactsOfHeroBase.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct ArtifactLocation;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CArtifactsOfHeroMain : public CArtifactsOfHeroBase
|
||||
{
|
||||
public:
|
||||
CArtifactsOfHeroMain(const Point & position);
|
||||
void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc);
|
||||
void pickUpArtifact(CHeroArtPlace & artPlace);
|
||||
};
|
41
client/widgets/CArtifactsOfHeroMarket.cpp
Normal file
41
client/widgets/CArtifactsOfHeroMarket.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* CArtifactsOfHeroMarket.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsOfHeroMarket.h"
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
|
||||
{
|
||||
init(
|
||||
std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1),
|
||||
std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1),
|
||||
position,
|
||||
std::bind(&CArtifactsOfHeroMarket::scrollBackpack, this, _1));
|
||||
};
|
||||
|
||||
void CArtifactsOfHeroMarket::scrollBackpack(int offset)
|
||||
{
|
||||
CArtifactsOfHeroBase::scrollBackpackForArtSet(offset, *curHero);
|
||||
|
||||
// We may have highlight on one of backpack artifacts
|
||||
if(selectArtCallback)
|
||||
{
|
||||
for(auto & artPlace : backpack)
|
||||
{
|
||||
if(artPlace->isMarked())
|
||||
{
|
||||
selectArtCallback(artPlace.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
safeRedraw();
|
||||
}
|
21
client/widgets/CArtifactsOfHeroMarket.h
Normal file
21
client/widgets/CArtifactsOfHeroMarket.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* CArtifactsOfHeroMarket.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CArtifactsOfHeroBase.h"
|
||||
|
||||
class CArtifactsOfHeroMarket : public CArtifactsOfHeroBase
|
||||
{
|
||||
public:
|
||||
std::function<void(CHeroArtPlace*)> selectArtCallback;
|
||||
|
||||
CArtifactsOfHeroMarket(const Point & position);
|
||||
void scrollBackpack(int offset) override;
|
||||
};
|
@ -19,6 +19,7 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
@ -488,11 +489,12 @@ CComponentBox::CComponentBox(std::vector<std::shared_ptr<CSelectableComponent>>
|
||||
|
||||
assert(!components.empty());
|
||||
|
||||
int key = SDLK_1;
|
||||
auto key = EShortcut::SELECT_INDEX_1;
|
||||
for(auto & comp : _components)
|
||||
{
|
||||
comp->onSelect = std::bind(&CComponentBox::selectionChanged, this, comp);
|
||||
comp->assignedKeys.insert(key++);
|
||||
comp->assignedKey = key;
|
||||
key = vstd::next(key, 1);
|
||||
}
|
||||
selectionChanged(_components.front());
|
||||
}
|
||||
|
@ -185,20 +185,17 @@ bool CGarrisonSlot::highlightOrDropArtifact()
|
||||
bool artSelected = false;
|
||||
if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt().get())) //dirty solution
|
||||
{
|
||||
std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->getCommonPart();
|
||||
const CArtifactInstance * art = nullptr;
|
||||
if(commonInfo)
|
||||
art = commonInfo->src.art;
|
||||
const auto pickedArtInst = chw->getPickedArtifact();
|
||||
|
||||
if(art)
|
||||
if(pickedArtInst)
|
||||
{
|
||||
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
|
||||
const auto * srcHero = chw->getHeroPickedArtifact();
|
||||
artSelected = true;
|
||||
if (myStack) // try dropping the artifact only if the slot isn't empty
|
||||
{
|
||||
ArtifactLocation src(srcHero, commonInfo->src.slotID);
|
||||
ArtifactLocation src(srcHero, ArtifactPosition::TRANSITION_POS);
|
||||
ArtifactLocation dst(myStack, ArtifactPosition::CREATURE_SLOT);
|
||||
if (art->canBePutAt(dst, true))
|
||||
if(pickedArtInst->canBePutAt(dst, true))
|
||||
{ //equip clicked stack
|
||||
if(dst.getArt())
|
||||
{
|
||||
|
363
client/widgets/CWindowWithArtifacts.cpp
Normal file
363
client/widgets/CWindowWithArtifacts.cpp
Normal file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* CWindowWithArtifacts.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CWindowWithArtifacts.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
|
||||
#include "CComponent.h"
|
||||
|
||||
#include "../windows/CHeroWindow.h"
|
||||
#include "../windows/CSpellWindow.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CGameInfo.h"
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
void CWindowWithArtifacts::addSet(CArtifactsOfHeroPtr artSet)
|
||||
{
|
||||
artSets.emplace_back(artSet);
|
||||
std::visit([this](auto artSetWeak)
|
||||
{
|
||||
auto artSet = artSetWeak.lock();
|
||||
artSet->leftClickCallback = std::bind(&CWindowWithArtifacts::leftClickArtPlaceHero, this, _1, _2);
|
||||
artSet->rightClickCallback = std::bind(&CWindowWithArtifacts::rightClickArtPlaceHero, this, _1, _2);
|
||||
}, artSet);
|
||||
}
|
||||
|
||||
const CGHeroInstance * CWindowWithArtifacts::getHeroPickedArtifact()
|
||||
{
|
||||
auto res = getState();
|
||||
if(res.has_value())
|
||||
return std::get<const CGHeroInstance*>(res.value());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CArtifactInstance * CWindowWithArtifacts::getPickedArtifact()
|
||||
{
|
||||
auto res = getState();
|
||||
if(res.has_value())
|
||||
return std::get<const CArtifactInstance*>(res.value());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace)
|
||||
{
|
||||
const auto artSetWeak = findAOHbyRef(artsInst);
|
||||
assert(artSetWeak.has_value());
|
||||
|
||||
if(artPlace.isLocked())
|
||||
return;
|
||||
|
||||
const auto checkSpecialArts = [](const CGHeroInstance * hero, CHeroArtPlace & artPlace) -> bool
|
||||
{
|
||||
if(artPlace.getArt()->getTypeId() == ArtifactID::SPELLBOOK)
|
||||
{
|
||||
GH.pushIntT<CSpellWindow>(hero, LOCPLINT, LOCPLINT->battleInt.get());
|
||||
return false;
|
||||
}
|
||||
if(artPlace.getArt()->getTypeId() == ArtifactID::CATAPULT)
|
||||
{
|
||||
// The Catapult must be equipped
|
||||
std::vector<std::shared_ptr<CComponent>> catapult(1, std::make_shared<CComponent>(CComponent::artifact, 3, 0));
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[312], catapult);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
std::visit(
|
||||
[checkSpecialArts, this, &artPlace](auto artSetWeak) -> void
|
||||
{
|
||||
const auto artSetPtr = artSetWeak.lock();
|
||||
|
||||
// Hero(Main, Exchange) window, Kingdom window, Altar window left click handler
|
||||
if constexpr(
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>> ||
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>> ||
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>>)
|
||||
{
|
||||
const auto pickedArtInst = getPickedArtifact();
|
||||
const auto heroPickedArt = getHeroPickedArtifact();
|
||||
const auto hero = artSetPtr->getHero();
|
||||
|
||||
if(pickedArtInst)
|
||||
{
|
||||
auto srcLoc = ArtifactLocation(heroPickedArt, ArtifactPosition::TRANSITION_POS);
|
||||
auto dstLoc = ArtifactLocation(hero, artPlace.slot);
|
||||
auto isTransferAllowed = false;
|
||||
|
||||
if(ArtifactUtils::isSlotBackpack(artPlace.slot))
|
||||
{
|
||||
if(pickedArtInst->artType->isBig())
|
||||
{
|
||||
// War machines cannot go to backpack
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % pickedArtInst->artType->getNameTranslated()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ArtifactUtils::isBackpackFreeSlots(heroPickedArt))
|
||||
isTransferAllowed = true;
|
||||
else
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("core.genrltxt.152"));
|
||||
}
|
||||
}
|
||||
// Check if artifact transfer is possible
|
||||
else if(pickedArtInst->canBePutAt(dstLoc, true) && (!artPlace.getArt() || hero->tempOwner == LOCPLINT->playerID))
|
||||
{
|
||||
isTransferAllowed = true;
|
||||
}
|
||||
if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>>)
|
||||
{
|
||||
if(hero != heroPickedArt)
|
||||
isTransferAllowed = false;
|
||||
}
|
||||
if(isTransferAllowed)
|
||||
artSetPtr->swapArtifacts(srcLoc, dstLoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(artPlace.getArt())
|
||||
{
|
||||
if(artSetPtr->getHero()->tempOwner == LOCPLINT->playerID)
|
||||
{
|
||||
if(checkSpecialArts(hero, artPlace))
|
||||
artSetPtr->pickUpArtifact(artPlace);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const auto artSlot : ArtifactUtils::unmovableSlots())
|
||||
if(artPlace.slot == artSlot)
|
||||
{
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[21]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Market window left click handler
|
||||
else if constexpr(std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMarket>>)
|
||||
{
|
||||
if(artSetPtr->selectArtCallback && artPlace.getArt())
|
||||
{
|
||||
if(artPlace.getArt()->artType->isTradable())
|
||||
{
|
||||
artSetPtr->unmarkSlots();
|
||||
artPlace.selectSlot(true);
|
||||
artSetPtr->selectArtCallback(&artPlace);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This item can't be traded
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[21]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, artSetWeak.value());
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace)
|
||||
{
|
||||
const auto artSetWeak = findAOHbyRef(artsInst);
|
||||
assert(artSetWeak.has_value());
|
||||
|
||||
if(artPlace.isLocked())
|
||||
return;
|
||||
|
||||
std::visit(
|
||||
[&artPlace](auto artSetWeak) -> void
|
||||
{
|
||||
const auto artSetPtr = artSetWeak.lock();
|
||||
|
||||
// Hero(Main, Exchange) window, Kingdom window right click handler
|
||||
if constexpr(
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMain>> ||
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>>)
|
||||
{
|
||||
if(artPlace.getArt())
|
||||
{
|
||||
if(ArtifactUtilsClient::askToDisassemble(artSetPtr->getHero(), artPlace.slot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(ArtifactUtilsClient::askToAssemble(artSetPtr->getHero(), artPlace.slot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(artPlace.text.size())
|
||||
artPlace.LRClickableAreaWTextComp::clickRight(boost::logic::tribool::true_value, false);
|
||||
}
|
||||
}
|
||||
// Altar window, Market window right click handler
|
||||
else if constexpr(
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroAltar>> ||
|
||||
std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroMarket>>)
|
||||
{
|
||||
if(artPlace.getArt() && artPlace.text.size())
|
||||
artPlace.LRClickableAreaWTextComp::clickRight(boost::logic::tribool::true_value, false);
|
||||
}
|
||||
}, artSetWeak.value());
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
|
||||
{
|
||||
updateSlots(artLoc.slot);
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
|
||||
{
|
||||
auto curState = getState();
|
||||
if(!curState.has_value())
|
||||
// Transition state. Nothing to do here. Just skip. Need to wait for final state.
|
||||
return;
|
||||
|
||||
// When moving one artifact onto another it leads to two art movements: dst->TRANSITION_POS; src->dst
|
||||
// However after first movement we pick the art from TRANSITION_POS and the second movement coming when
|
||||
// we have a different artifact may look surprising... but it's valid.
|
||||
|
||||
auto pickedArtInst = std::get<const CArtifactInstance*>(curState.value());
|
||||
assert(srcLoc.isHolder(std::get<const CGHeroInstance*>(curState.value())));
|
||||
assert(srcLoc.getArt() == pickedArtInst);
|
||||
|
||||
auto artifactMovedBody = [this, withRedraw, &srcLoc, &destLoc, &pickedArtInst](auto artSetWeak) -> void
|
||||
{
|
||||
auto artSetPtr = artSetWeak.lock();
|
||||
if(artSetPtr)
|
||||
{
|
||||
const auto hero = artSetPtr->getHero();
|
||||
if(artSetPtr->active)
|
||||
{
|
||||
if(pickedArtInst)
|
||||
{
|
||||
CCS->curh->dragAndDropCursor("artifact", pickedArtInst->artType->getIconIndex());
|
||||
if(srcLoc.isHolder(hero) || !std::is_same_v<decltype(artSetWeak), std::weak_ptr<CArtifactsOfHeroKingdom>>)
|
||||
artSetPtr->markPossibleSlots(pickedArtInst, hero->tempOwner == LOCPLINT->playerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
artSetPtr->unmarkSlots();
|
||||
CCS->curh->dragAndDropCursor(nullptr);
|
||||
}
|
||||
}
|
||||
if(withRedraw)
|
||||
{
|
||||
artSetPtr->updateWornSlots();
|
||||
artSetPtr->updateBackpackSlots();
|
||||
|
||||
// Update arts bonuses on window.
|
||||
// TODO rework this part when CHeroWindow and CExchangeWindow are reworked
|
||||
if(auto * chw = dynamic_cast<CHeroWindow*>(this))
|
||||
{
|
||||
chw->update(hero, true);
|
||||
}
|
||||
else if(auto * cew = dynamic_cast<CExchangeWindow*>(this))
|
||||
{
|
||||
cew->updateWidgets();
|
||||
}
|
||||
artSetPtr->safeRedraw();
|
||||
}
|
||||
|
||||
// Make sure the status bar is updated so it does not display old text
|
||||
if(destLoc.isHolder(hero))
|
||||
{
|
||||
if(auto artPlace = artSetPtr->getArtPlace(destLoc.slot))
|
||||
artPlace->hover(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for(auto artSetWeak : artSets)
|
||||
std::visit(artifactMovedBody, artSetWeak);
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation & artLoc)
|
||||
{
|
||||
updateSlots(artLoc.slot);
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation & artLoc)
|
||||
{
|
||||
updateSlots(artLoc.slot);
|
||||
}
|
||||
|
||||
void CWindowWithArtifacts::updateSlots(const ArtifactPosition & slot)
|
||||
{
|
||||
auto updateSlotBody = [slot](auto artSetWeak) -> void
|
||||
{
|
||||
if(const auto artSetPtr = artSetWeak.lock())
|
||||
{
|
||||
if(ArtifactUtils::isSlotEquipment(slot))
|
||||
artSetPtr->updateWornSlots();
|
||||
else if(ArtifactUtils::isSlotBackpack(slot))
|
||||
artSetPtr->updateBackpackSlots();
|
||||
|
||||
artSetPtr->safeRedraw();
|
||||
}
|
||||
};
|
||||
|
||||
for(auto artSetWeak : artSets)
|
||||
std::visit(updateSlotBody, artSetWeak);
|
||||
}
|
||||
|
||||
std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> CWindowWithArtifacts::getState()
|
||||
{
|
||||
const CArtifactInstance * artInst = nullptr;
|
||||
const CGHeroInstance * hero = nullptr;
|
||||
size_t pickedCnt = 0;
|
||||
|
||||
auto getHeroArtBody = [&hero, &artInst, &pickedCnt](auto artSetWeak) -> void
|
||||
{
|
||||
auto artSetPtr = artSetWeak.lock();
|
||||
if(artSetPtr)
|
||||
{
|
||||
if(const auto art = artSetPtr->getPickedArtifact())
|
||||
{
|
||||
artInst = art;
|
||||
hero = artSetPtr->getHero();
|
||||
pickedCnt += hero->artifactsTransitionPos.size();
|
||||
}
|
||||
}
|
||||
};
|
||||
for(auto artSetWeak : artSets)
|
||||
std::visit(getHeroArtBody, artSetWeak);
|
||||
|
||||
// The state is possible when the hero has placed an artifact in the ArtifactPosition::TRANSITION_POS,
|
||||
// and the previous artifact has not yet removed from the ArtifactPosition::TRANSITION_POS.
|
||||
// This is a transitional state. Then return nullopt.
|
||||
if(pickedCnt > 1)
|
||||
return std::nullopt;
|
||||
else
|
||||
return std::make_tuple(hero, artInst);
|
||||
}
|
||||
|
||||
std::optional<CWindowWithArtifacts::CArtifactsOfHeroPtr> CWindowWithArtifacts::findAOHbyRef(CArtifactsOfHeroBase & artsInst)
|
||||
{
|
||||
std::optional<CArtifactsOfHeroPtr> res;
|
||||
|
||||
auto findAOHBody = [&res, &artsInst](auto & artSetWeak) -> void
|
||||
{
|
||||
if(&artsInst == artSetWeak.lock().get())
|
||||
res = artSetWeak;
|
||||
};
|
||||
|
||||
for(auto artSetWeak : artSets)
|
||||
{
|
||||
std::visit(findAOHBody, artSetWeak);
|
||||
if(res.has_value())
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
44
client/widgets/CWindowWithArtifacts.h
Normal file
44
client/widgets/CWindowWithArtifacts.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* CWindowWithArtifacts.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CArtifactHolder.h"
|
||||
#include "CArtifactsOfHeroMain.h"
|
||||
#include "CArtifactsOfHeroKingdom.h"
|
||||
#include "CArtifactsOfHeroAltar.h"
|
||||
#include "CArtifactsOfHeroMarket.h"
|
||||
|
||||
class CWindowWithArtifacts : public CArtifactHolder
|
||||
{
|
||||
public:
|
||||
using CArtifactsOfHeroPtr = std::variant<
|
||||
std::weak_ptr<CArtifactsOfHeroMarket>,
|
||||
std::weak_ptr<CArtifactsOfHeroAltar>,
|
||||
std::weak_ptr<CArtifactsOfHeroKingdom>,
|
||||
std::weak_ptr<CArtifactsOfHeroMain>>;
|
||||
|
||||
void addSet(CArtifactsOfHeroPtr artSet);
|
||||
const CGHeroInstance * getHeroPickedArtifact();
|
||||
const CArtifactInstance * getPickedArtifact();
|
||||
void leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace);
|
||||
void rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace);
|
||||
|
||||
void artifactRemoved(const ArtifactLocation & artLoc) override;
|
||||
void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override;
|
||||
void artifactDisassembled(const ArtifactLocation & artLoc) override;
|
||||
void artifactAssembled(const ArtifactLocation & artLoc) override;
|
||||
|
||||
private:
|
||||
std::vector<CArtifactsOfHeroPtr> artSets;
|
||||
|
||||
void updateSlots(const ArtifactPosition & slot);
|
||||
std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> getState();
|
||||
std::optional<CArtifactsOfHeroPtr> findAOHbyRef(CArtifactsOfHeroBase & artsInst);
|
||||
};
|
@ -200,7 +200,7 @@ void CMinorResDataBar::showAll(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::showAll(to);
|
||||
|
||||
for (EGameResID i=EGameResID::WOOD; i<=EGameResID::GOLD; vstd::advance(i, 1))
|
||||
for (GameResID i=EGameResID::WOOD; i<=EGameResID::GOLD; ++i)
|
||||
{
|
||||
std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(i));
|
||||
|
||||
|
@ -25,7 +25,7 @@ class CAnimation;
|
||||
class CObjectList : public CIntObject
|
||||
{
|
||||
public:
|
||||
typedef std::function<std::shared_ptr<CIntObject>(size_t)> CreateFunc;
|
||||
using CreateFunc = std::function<std::shared_ptr<CIntObject>(size_t)>;
|
||||
|
||||
private:
|
||||
CreateFunc createObject;
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../adventureMap/CInGameConsole.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
@ -555,12 +556,12 @@ void CTextInput::clickLeft(tribool down, bool previousState)
|
||||
giveFocus();
|
||||
}
|
||||
|
||||
void CTextInput::keyPressed(const SDL_Keycode & key)
|
||||
void CTextInput::keyPressed(EShortcut key)
|
||||
{
|
||||
if(!focus)
|
||||
return;
|
||||
|
||||
if(key == SDLK_TAB)
|
||||
if(key == EShortcut::GLOBAL_MOVE_FOCUS)
|
||||
{
|
||||
moveFocus();
|
||||
GH.breakEventHandling();
|
||||
@ -571,9 +572,7 @@ void CTextInput::keyPressed(const SDL_Keycode & key)
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_DELETE: // have index > ' ' so it won't be filtered out by default section
|
||||
return;
|
||||
case SDLK_BACKSPACE:
|
||||
case EShortcut::GLOBAL_BACKSPACE:
|
||||
if(!newText.empty())
|
||||
{
|
||||
TextOperations::trimRightUnicode(newText);
|
||||
@ -608,9 +607,9 @@ void CTextInput::setText(const std::string & nText, bool callCb)
|
||||
cb(text);
|
||||
}
|
||||
|
||||
bool CTextInput::captureThisKey(const SDL_Keycode & key)
|
||||
bool CTextInput::captureThisKey(EShortcut key)
|
||||
{
|
||||
if(key == SDLK_RETURN || key == SDLK_KP_ENTER || key == SDLK_ESCAPE)
|
||||
if(key == EShortcut::GLOBAL_RETURN)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -225,9 +225,9 @@ public:
|
||||
CTextInput(const Rect & Pos, std::shared_ptr<IImage> srf);
|
||||
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
|
||||
bool captureThisKey(const SDL_Keycode & key) override;
|
||||
bool captureThisKey(EShortcut key) override;
|
||||
|
||||
void textInputed(const std::string & enteredText) override;
|
||||
void textEdited(const std::string & enteredText) override;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
@ -1184,8 +1185,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
|
||||
income = std::make_shared<CLabel>(195, 443, FONT_SMALL, ETextAlignment::CENTER);
|
||||
icon = std::make_shared<CAnimImage>("ITPT", 0, 0, 15, 387);
|
||||
|
||||
exit = std::make_shared<CButton>(Point(744, 544), "TSBTNS", CButton::tooltip(CGI->generaltexth->tcommands[8]), [&](){close();}, SDLK_RETURN);
|
||||
exit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>(Point(744, 544), "TSBTNS", CButton::tooltip(CGI->generaltexth->tcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN);
|
||||
exit->setImageOrder(4, 5, 6, 7);
|
||||
|
||||
auto split = std::make_shared<CButton>(Point(744, 382), "TSBTNS", CButton::tooltip(CGI->generaltexth->tcommands[3]), [&]()
|
||||
@ -1308,20 +1308,20 @@ void CCastleInterface::recreateIcons()
|
||||
|
||||
}
|
||||
|
||||
void CCastleInterface::keyPressed(const SDL_Keycode & key)
|
||||
void CCastleInterface::keyPressed(EShortcut key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_UP:
|
||||
case EShortcut::MOVE_UP:
|
||||
townlist->selectPrev();
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
case EShortcut::MOVE_DOWN:
|
||||
townlist->selectNext();
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
case EShortcut::TOWN_SWAP_ARMIES:
|
||||
heroes->swapArmies();
|
||||
break;
|
||||
case SDLK_t:
|
||||
case EShortcut::TOWN_OPEN_TAVERN:
|
||||
if(town->hasBuilt(BuildingID::TAVERN))
|
||||
LOCPLINT->showTavernWindow(town);
|
||||
break;
|
||||
@ -1420,8 +1420,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
|
||||
statusbar = CGStatusBar::create(statusbarBackground);
|
||||
|
||||
title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->getNameTranslated());
|
||||
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, SDLK_RETURN);
|
||||
exit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN);
|
||||
|
||||
auto & boxList = town->town->clientInfo.hallSlots;
|
||||
boxes.resize(boxList.size());
|
||||
@ -1486,11 +1485,11 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
|
||||
std::string tooltipYes = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->getNameTranslated());
|
||||
std::string tooltipNo = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % building->getNameTranslated());
|
||||
|
||||
buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&](){ buyFunc(); }, SDLK_RETURN);
|
||||
buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&](){ buyFunc(); }, EShortcut::GLOBAL_ACCEPT);
|
||||
buy->setBorderColor(Colors::METALLIC_GOLD);
|
||||
buy->block(state!=7 || LOCPLINT->playerID != town->tempOwner);
|
||||
|
||||
cancel = std::make_shared<CButton>(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo), [&](){ close();}, SDLK_ESCAPE);
|
||||
cancel = std::make_shared<CButton>(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo), [&](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
cancel->setBorderColor(Colors::METALLIC_GOLD);
|
||||
}
|
||||
}
|
||||
@ -1596,8 +1595,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
|
||||
title = std::make_shared<CLabel>(400, 12, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE, fortBuilding->getNameTranslated());
|
||||
|
||||
std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->getNameTranslated());
|
||||
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(text), [&](){ close(); }, SDLK_RETURN);
|
||||
exit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_RETURN);
|
||||
|
||||
std::vector<Point> positions =
|
||||
{
|
||||
@ -1785,8 +1783,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem)
|
||||
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 7, 556);
|
||||
statusbar = CGStatusBar::create(statusbarBackground);
|
||||
|
||||
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[593]), [&](){ close(); }, SDLK_RETURN);
|
||||
exit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[593]), [&](){ close(); }, EShortcut::GLOBAL_RETURN);
|
||||
|
||||
static const std::vector<std::vector<Point> > positions =
|
||||
{
|
||||
@ -1866,10 +1863,10 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
|
||||
std::to_string(aid.toArtifact(CGI->artifacts())->getPrice()));
|
||||
|
||||
std::string text = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % creature->getNameSingularTranslated());
|
||||
buy = std::make_shared<CButton>(Point(42, 312), "IBUY30.DEF", CButton::tooltip(text), [&](){ close(); }, SDLK_RETURN);
|
||||
buy = std::make_shared<CButton>(Point(42, 312), "IBUY30.DEF", CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);
|
||||
|
||||
text = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % creature->getNameSingularTranslated());
|
||||
cancel = std::make_shared<CButton>(Point(224, 312), "ICANCEL.DEF", CButton::tooltip(text), [&](){ close(); }, SDLK_ESCAPE);
|
||||
cancel = std::make_shared<CButton>(Point(224, 312), "ICANCEL.DEF", CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_CANCEL);
|
||||
|
||||
if(possible)
|
||||
buy->addCallback([=](){ LOCPLINT->cb->buyArtifact(LOCPLINT->cb->getHero(hid),aid); });
|
||||
|
@ -246,7 +246,7 @@ public:
|
||||
|
||||
void castleTeleport(int where);
|
||||
void townChange();
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
|
||||
void close();
|
||||
void addBuilding(BuildingID bid);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/ObjectLists.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -284,7 +285,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[12], onDismiss, nullptr);
|
||||
};
|
||||
dismiss = std::make_shared<CButton>(Point(5, 5),"IVIEWCR2.DEF", CGI->generaltexth->zelp[445], onClick, SDLK_d);
|
||||
dismiss = std::make_shared<CButton>(Point(5, 5),"IVIEWCR2.DEF", CGI->generaltexth->zelp[445], onClick, EShortcut::HERO_DISMISS);
|
||||
}
|
||||
|
||||
if(parent->info->upgradeInfo && !parent->info->commander)
|
||||
@ -321,14 +322,12 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314], resComps);
|
||||
}
|
||||
};
|
||||
auto upgradeBtn = std::make_shared<CButton>(Point(221 + (int)buttonIndex * 40, 5), "stackWindow/upgradeButton", CGI->generaltexth->zelp[446], onClick, SDLK_1);
|
||||
auto upgradeBtn = std::make_shared<CButton>(Point(221 + (int)buttonIndex * 40, 5), "stackWindow/upgradeButton", CGI->generaltexth->zelp[446], onClick);
|
||||
|
||||
upgradeBtn->addOverlay(std::make_shared<CAnimImage>("CPRSMALL", VLC->creh->objects[upgradeInfo.info.newID[buttonIndex]]->getIconIndex()));
|
||||
|
||||
if(buttonsToCreate == 1) // single upgrade avaialbe
|
||||
{
|
||||
upgradeBtn->assignedKeys.insert(SDLK_u);
|
||||
}
|
||||
upgradeBtn->assignedKey = EShortcut::RECRUITMENT_UPGRADE;
|
||||
|
||||
upgrade[buttonIndex] = upgradeBtn;
|
||||
}
|
||||
@ -356,8 +355,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
|
||||
parent->switchButtons[parent->activeTab]->disable();
|
||||
}
|
||||
|
||||
exit = std::make_shared<CButton>(Point(382, 5), "hsbtns.def", CGI->generaltexth->zelp[447], [=](){ parent->close(); }, SDLK_RETURN);
|
||||
exit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>(Point(382, 5), "hsbtns.def", CGI->generaltexth->zelp[447], [=](){ parent->close(); }, EShortcut::GLOBAL_RETURN);
|
||||
}
|
||||
|
||||
CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, int yOffset)
|
||||
@ -457,8 +455,8 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i
|
||||
|
||||
abilities = std::make_shared<CListBox>(onCreate, Point(38, 3+pos.h), Point(63, 0), 6, abilitiesCount);
|
||||
|
||||
leftBtn = std::make_shared<CButton>(Point(10, pos.h + 6), "hsbtns3.def", CButton::tooltip(), [=](){ abilities->moveToPrev(); }, SDLK_LEFT);
|
||||
rightBtn = std::make_shared<CButton>(Point(411, pos.h + 6), "hsbtns5.def", CButton::tooltip(), [=](){ abilities->moveToNext(); }, SDLK_RIGHT);
|
||||
leftBtn = std::make_shared<CButton>(Point(10, pos.h + 6), "hsbtns3.def", CButton::tooltip(), [=](){ abilities->moveToPrev(); }, EShortcut::MOVE_LEFT);
|
||||
rightBtn = std::make_shared<CButton>(Point(411, pos.h + 6), "hsbtns5.def", CButton::tooltip(), [=](){ abilities->moveToNext(); }, EShortcut::MOVE_RIGHT);
|
||||
|
||||
if(abilitiesCount <= 6)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
@ -42,9 +43,10 @@ TConstBonusListPtr CHeroWithMaybePickedArtifact::getAllBonuses(const CSelector &
|
||||
TConstBonusListPtr heroBonuses = hero->getAllBonuses(selector, limit, hero, cachingStr);
|
||||
TConstBonusListPtr bonusesFromPickedUpArtifact;
|
||||
|
||||
std::shared_ptr<CArtifactsOfHero::SCommonPart> cp = cww->getCommonPart();
|
||||
if(cp && cp->src.art && cp->src.valid() && cp->src.AOH && cp->src.AOH->getHero() == hero)
|
||||
bonusesFromPickedUpArtifact = cp->src.art->getAllBonuses(selector, limit, hero);
|
||||
const auto pickedArtInst = cww->getPickedArtifact();
|
||||
|
||||
if(pickedArtInst)
|
||||
bonusesFromPickedUpArtifact = pickedArtInst->getAllBonuses(selector, limit, hero);
|
||||
else
|
||||
bonusesFromPickedUpArtifact = TBonusListPtr(new BonusList());
|
||||
|
||||
@ -118,22 +120,21 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
|
||||
|
||||
statusbar = CGStatusBar::create(7, 559, "ADROLLVR.bmp", 660);
|
||||
|
||||
quitButton = std::make_shared<CButton>(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [=](){ close(); }, SDLK_RETURN);
|
||||
quitButton->assignedKeys.insert(SDLK_ESCAPE);
|
||||
quitButton = std::make_shared<CButton>(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [=](){ close(); }, EShortcut::GLOBAL_RETURN);
|
||||
|
||||
dismissLabel = std::make_shared<CTextBox>(CGI->generaltexth->jktexts[8], Rect(370, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
|
||||
dismissButton = std::make_shared<CButton>(Point(454, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, SDLK_d);
|
||||
dismissButton = std::make_shared<CButton>(Point(454, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS);
|
||||
|
||||
questlogLabel = std::make_shared<CTextBox>(CGI->generaltexth->jktexts[9], Rect(510, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
|
||||
questlogButton = std::make_shared<CButton>(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, SDLK_q);
|
||||
questlogButton = std::make_shared<CButton>(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
|
||||
|
||||
formations = std::make_shared<CToggleGroup>(0);
|
||||
formations->addToggle(0, std::make_shared<CToggleButton>(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, SDLK_t));
|
||||
formations->addToggle(1, std::make_shared<CToggleButton>(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, SDLK_l));
|
||||
formations->addToggle(0, std::make_shared<CToggleButton>(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, EShortcut::HERO_TIGHT_FORMATION));
|
||||
formations->addToggle(1, std::make_shared<CToggleButton>(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, EShortcut::HERO_LOOSE_FORMATION));
|
||||
|
||||
if(hero->commander)
|
||||
{
|
||||
commanderButton = std::make_shared<CButton>(Point(317, 18), "buttons/commander", CButton::tooltipLocalized("vcmi.heroWindow.openCommander"), [&](){ commanderWindow(); }, SDLK_c);
|
||||
commanderButton = std::make_shared<CButton>(Point(317, 18), "buttons/commander", CButton::tooltipLocalized("vcmi.heroWindow.openCommander"), [&](){ commanderWindow(); }, EShortcut::HERO_COMMANDER);
|
||||
}
|
||||
|
||||
//right list of heroes
|
||||
@ -223,7 +224,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
|
||||
specImage->setFrame(curHero->type->imageIndex);
|
||||
specName->setText(curHero->type->getSpecialtyNameTranslated());
|
||||
|
||||
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b);
|
||||
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, EShortcut::HERO_TOGGLE_TACTICS);
|
||||
tacticsButton->addHoverText(CButton::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]);
|
||||
|
||||
dismissButton->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->getNameTranslated() % curHero->type->heroClass->getNameTranslated()));
|
||||
@ -244,7 +245,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
|
||||
}
|
||||
if(!arts)
|
||||
{
|
||||
arts = std::make_shared<CArtifactsOfHero>(Point(-65, -8), true);
|
||||
arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8));
|
||||
arts->setHero(curHero);
|
||||
addSet(arts);
|
||||
}
|
||||
@ -354,25 +355,23 @@ void CHeroWindow::dismissCurrent()
|
||||
|
||||
void CHeroWindow::commanderWindow()
|
||||
{
|
||||
//bool artSelected = false;
|
||||
std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = getCommonPart();
|
||||
const auto pickedArtInst = getPickedArtifact();
|
||||
const auto hero = getHeroPickedArtifact();
|
||||
|
||||
if(const CArtifactInstance *art = commonInfo->src.art)
|
||||
if(pickedArtInst)
|
||||
{
|
||||
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
|
||||
//artSelected = true;
|
||||
const auto freeSlot = ArtifactUtils::getArtAnyPosition(curHero->commander, art->artType->getId());
|
||||
const auto freeSlot = ArtifactUtils::getArtAnyPosition(curHero->commander, pickedArtInst->getTypeId());
|
||||
if(freeSlot < ArtifactPosition::COMMANDER_AFTER_LAST) //we don't want to put it in commander's backpack!
|
||||
{
|
||||
ArtifactLocation src(srcHero, commonInfo->src.slotID);
|
||||
ArtifactLocation src(hero, ArtifactPosition::TRANSITION_POS);
|
||||
ArtifactLocation dst(curHero->commander.get(), freeSlot);
|
||||
|
||||
if(art->canBePutAt(dst, true))
|
||||
if(pickedArtInst->canBePutAt(dst, true))
|
||||
{ //equip clicked stack
|
||||
if(dst.getArt())
|
||||
{
|
||||
LOCPLINT->cb->swapArtifacts (dst, ArtifactLocation(srcHero,
|
||||
ArtifactUtils::getArtBackpackPosition(srcHero, art->getTypeId())));
|
||||
LOCPLINT->cb->swapArtifacts(dst, ArtifactLocation(hero,
|
||||
ArtifactUtils::getArtBackpackPosition(hero, pickedArtInst->getTypeId())));
|
||||
}
|
||||
LOCPLINT->cb->swapArtifacts(src, dst);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../lib/HeroBonus.h"
|
||||
#include "../widgets/CArtifactHolder.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "../widgets/CGarrisonInt.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -25,7 +25,7 @@ class CHeroWindow;
|
||||
class LClickableAreaHero;
|
||||
class LRClickableAreaWText;
|
||||
class LRClickableAreaWTextComp;
|
||||
class CArtifactsOfHero;
|
||||
class CArtifactsOfHeroMain;
|
||||
class MoraleLuckBox;
|
||||
class CToggleButton;
|
||||
class CToggleGroup;
|
||||
@ -105,7 +105,7 @@ class CHeroWindow : public CStatusbarWindow, public CGarrisonHolder, public CWin
|
||||
std::shared_ptr<CToggleGroup> formations;
|
||||
|
||||
std::shared_ptr<CGarrisonInt> garr;
|
||||
std::shared_ptr<CArtifactsOfHero> arts;
|
||||
std::shared_ptr<CArtifactsOfHeroMain> arts;
|
||||
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../adventureMap/CResDataBar.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
@ -613,15 +614,14 @@ void CKingdomInterface::generateButtons()
|
||||
|
||||
//Main control buttons
|
||||
btnHeroes = std::make_shared<CButton>(Point(748, 28+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->overview[11], CGI->generaltexth->overview[6]),
|
||||
std::bind(&CKingdomInterface::activateTab, this, 0), SDLK_h);
|
||||
std::bind(&CKingdomInterface::activateTab, this, 0), EShortcut::KINGDOM_HEROES_TAB);
|
||||
btnHeroes->block(true);
|
||||
|
||||
btnTowns = std::make_shared<CButton>(Point(748, 64+footerPos), "OVBUTN6.DEF", CButton::tooltip(CGI->generaltexth->overview[12], CGI->generaltexth->overview[7]),
|
||||
std::bind(&CKingdomInterface::activateTab, this, 1), SDLK_t);
|
||||
std::bind(&CKingdomInterface::activateTab, this, 1), EShortcut::KINGDOM_TOWNS_TAB);
|
||||
|
||||
btnExit = std::make_shared<CButton>(Point(748,99+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[600]),
|
||||
std::bind(&CKingdomInterface::close, this), SDLK_RETURN);
|
||||
btnExit->assignedKeys.insert(SDLK_ESCAPE);
|
||||
std::bind(&CKingdomInterface::close, this), EShortcut::GLOBAL_RETURN);
|
||||
btnExit->setImageOrder(3, 4, 5, 6);
|
||||
|
||||
//Object list control buttons
|
||||
@ -826,7 +826,7 @@ public:
|
||||
background = std::make_shared<CAnimImage>("OVSLOT", 4);
|
||||
pos = background->pos;
|
||||
for(int i=0; i<9; i++)
|
||||
arts.push_back(std::make_shared<CHeroArtPlace>(Point(270+i*48, 65)));
|
||||
arts.push_back(std::make_shared<CHeroArtPlace>(Point(269+i*48, 66)));
|
||||
}
|
||||
};
|
||||
|
||||
@ -846,7 +846,7 @@ public:
|
||||
btnLeft = std::make_shared<CButton>(Point(269, 66), "HSBTNS3", CButton::tooltip(), 0);
|
||||
btnRight = std::make_shared<CButton>(Point(675, 66), "HSBTNS5", CButton::tooltip(), 0);
|
||||
for(int i=0; i<8; i++)
|
||||
arts.push_back(std::make_shared<CHeroArtPlace>(Point(295+i*48, 65)));
|
||||
arts.push_back(std::make_shared<CHeroArtPlace>(Point(294+i*48, 66)));
|
||||
}
|
||||
};
|
||||
|
||||
@ -872,7 +872,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero)
|
||||
assert(arts1->arts.size() == 9);
|
||||
assert(arts2->arts.size() == 9);
|
||||
|
||||
CArtifactsOfHero::ArtPlaceMap arts =
|
||||
CArtifactsOfHeroMain::ArtPlaceMap arts =
|
||||
{
|
||||
{ArtifactPosition::HEAD, arts1->arts[0]},
|
||||
{ArtifactPosition::SHOULDERS,arts1->arts[1]},
|
||||
@ -896,7 +896,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero)
|
||||
};
|
||||
|
||||
|
||||
heroArts = std::make_shared<CArtifactsOfHero>(arts, backpack->arts, backpack->btnLeft, backpack->btnRight, true);
|
||||
heroArts = std::make_shared<CArtifactsOfHeroKingdom>(arts, backpack->arts, backpack->btnLeft, backpack->btnRight);
|
||||
heroArts->setHero(hero);
|
||||
|
||||
artsTabs = std::make_shared<CTabbedInt>(std::bind(&CHeroItem::onTabSelected, this, _1));
|
||||
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../widgets/CArtifactHolder.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "../widgets/CGarrisonInt.h"
|
||||
|
||||
class CButton;
|
||||
@ -309,7 +309,7 @@ class CHeroItem : public CIntObject, public CGarrisonHolder
|
||||
std::shared_ptr<CIntObject> onTabSelected(size_t index);
|
||||
|
||||
public:
|
||||
std::shared_ptr<CArtifactsOfHero> heroArts;
|
||||
std::shared_ptr<CArtifactsOfHeroKingdom> heroArts;
|
||||
|
||||
void updateGarrisons() override;
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../adventureMap/CResDataBar.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../mapView/MapView.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/Images.h"
|
||||
@ -35,8 +36,7 @@ CPuzzleWindow::CPuzzleWindow(const int3 & GrailPos, double discoveredRatio)
|
||||
|
||||
CCS->soundh->playSound(soundBase::OBELISK);
|
||||
|
||||
quitb = std::make_shared<CButton>(Point(670, 538), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CPuzzleWindow::close, this), SDLK_RETURN);
|
||||
quitb->assignedKeys.insert(SDLK_ESCAPE);
|
||||
quitb = std::make_shared<CButton>(Point(670, 538), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CPuzzleWindow::close, this), EShortcut::GLOBAL_RETURN);
|
||||
quitb->setBorderColor(Colors::METALLIC_GOLD);
|
||||
|
||||
mapView = std::make_shared<PuzzleMapView>(Point(8,9), Point(591, 544), grailPos);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../adventureMap/CAdventureMapInterface.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
@ -127,7 +128,7 @@ CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests)
|
||||
minimap = std::make_shared<CQuestMinimap>(Rect(12, 12, 169, 169));
|
||||
// TextBox have it's own 4 pixel padding from top at least for English. To achieve 10px from both left and top only add 6px margin
|
||||
description = std::make_shared<CTextBox>("", Rect(205, 18, 385, DESCRIPTION_HEIGHT_MAX), CSlider::BROWN, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE);
|
||||
ok = std::make_shared<CButton>(Point(539, 398), "IOKAY.DEF", CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), SDLK_RETURN);
|
||||
ok = std::make_shared<CButton>(Point(539, 398), "IOKAY.DEF", CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), EShortcut::GLOBAL_ACCEPT);
|
||||
// Both button and lable are shifted to -2px by x and y to not make them actually look like they're on same line with quests list and ok button
|
||||
hideCompleteButton = std::make_shared<CToggleButton>(Point(10, 396), "sysopchk.def", CButton::tooltipLocalized("vcmi.questLog.hideComplete"), std::bind(&CQuestLog::toggleComplete, this, _1));
|
||||
hideCompleteLabel = std::make_shared<CLabel>(46, 398, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->translate("vcmi.questLog.hideComplete.hover"));
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "../battle/BattleInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
@ -409,27 +410,24 @@ void CSpellWindow::turnPageRight()
|
||||
CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15);
|
||||
}
|
||||
|
||||
void CSpellWindow::keyPressed(const SDL_Keycode & key)
|
||||
void CSpellWindow::keyPressed(EShortcut key)
|
||||
{
|
||||
if(key == SDLK_ESCAPE || key == SDLK_RETURN)
|
||||
switch(key)
|
||||
{
|
||||
fexitb();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_LEFT:
|
||||
case EShortcut::GLOBAL_RETURN:
|
||||
fexitb();
|
||||
break;
|
||||
|
||||
case EShortcut::MOVE_LEFT:
|
||||
fLcornerb();
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
case EShortcut::MOVE_RIGHT:
|
||||
fRcornerb();
|
||||
break;
|
||||
case SDLK_UP:
|
||||
case SDLK_DOWN:
|
||||
case EShortcut::MOVE_UP:
|
||||
case EShortcut::MOVE_DOWN:
|
||||
{
|
||||
bool down = key == SDLK_DOWN;
|
||||
bool down = key == EShortcut::MOVE_DOWN;
|
||||
static const int schoolsOrder[] = { 0, 3, 1, 2, 4 };
|
||||
int index = -1;
|
||||
while(schoolsOrder[++index] != selectedTab);
|
||||
@ -439,38 +437,12 @@ void CSpellWindow::keyPressed(const SDL_Keycode & key)
|
||||
selectSchool(schoolsOrder[index]);
|
||||
break;
|
||||
}
|
||||
case SDLK_c:
|
||||
case EShortcut::SPELLBOOK_TAB_COMBAT:
|
||||
fbattleSpellsb();
|
||||
break;
|
||||
case SDLK_a:
|
||||
case EShortcut::SPELLBOOK_TAB_ADVENTURE:
|
||||
fadvSpellsb();
|
||||
break;
|
||||
default://to get rid of warnings
|
||||
break;
|
||||
}
|
||||
|
||||
//alt + 1234567890-= casts spell from 1 - 12 slot
|
||||
if(GH.isKeyboardAltDown())
|
||||
{
|
||||
SDL_Keycode hlpKey = key;
|
||||
if(CGuiHandler::isNumKey(hlpKey, false))
|
||||
{
|
||||
if(hlpKey == SDLK_KP_PLUS)
|
||||
hlpKey = SDLK_EQUALS;
|
||||
else
|
||||
hlpKey = CGuiHandler::numToDigit(hlpKey);
|
||||
}
|
||||
|
||||
static const SDL_Keycode spellSelectors[] = {SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_0, SDLK_MINUS, SDLK_EQUALS};
|
||||
|
||||
int index = -1;
|
||||
while(++index < std::size(spellSelectors) && spellSelectors[index] != hlpKey);
|
||||
if(index >= std::size(spellSelectors))
|
||||
return;
|
||||
|
||||
//try casting spell
|
||||
spellAreas[index]->clickLeft(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
void selectSchool(int school); //schools: 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic, 4 - all schools
|
||||
int pagesWithinCurrentTab();
|
||||
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
};
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "../widgets/Images.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
@ -179,24 +180,26 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
|
||||
if(type == ARTIFACT_PLACEHOLDER)
|
||||
{
|
||||
CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
|
||||
if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art)
|
||||
const auto pickedArtInst = aw->getPickedArtifact();
|
||||
|
||||
auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(aw->arts);
|
||||
if(pickedArtInst)
|
||||
{
|
||||
aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this->shared_from_this(), movedArt);
|
||||
artifactsOfHero->pickedArtMoveToAltar(ArtifactPosition::TRANSITION_POS);
|
||||
aw->moveArtToAltar(this->shared_from_this(), pickedArtInst);
|
||||
}
|
||||
else if(const CArtifactInstance *art = getArtInstance())
|
||||
{
|
||||
aw->arts->commonInfo->src.AOH = aw->arts.get();
|
||||
aw->arts->commonInfo->src.art = art;
|
||||
aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art);
|
||||
aw->arts->markPossibleSlots(art);
|
||||
|
||||
//aw->arts->commonInfo->dst.AOH = aw->arts;
|
||||
CCS->curh->dragAndDropCursor("artifact", art->artType->getIconIndex());
|
||||
|
||||
aw->arts->artifactsOnAltar.erase(art);
|
||||
const auto hero = artifactsOfHero->getHero();
|
||||
const auto slot = hero->getSlotByInstance(art);
|
||||
assert(slot != ArtifactPosition::PRE_FIRST);
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero, slot),
|
||||
ArtifactLocation(hero, ArtifactPosition::TRANSITION_POS));
|
||||
artifactsOfHero->pickedArtFromSlot = slot;
|
||||
artifactsOfHero->artifactsOnAltar.erase(art);
|
||||
setID(-1);
|
||||
subtitle.clear();
|
||||
aw->deal->block(!aw->arts->artifactsOnAltar.size());
|
||||
aw->deal->block(!artifactsOfHero->artifactsOnAltar.size());
|
||||
}
|
||||
|
||||
aw->calcTotalExp();
|
||||
@ -387,18 +390,25 @@ void CTradeWindow::initItems(bool Left)
|
||||
}
|
||||
else //ARTIFACT_EXP
|
||||
{
|
||||
xOffset = -363;
|
||||
xOffset = -365;
|
||||
yOffset = -12;
|
||||
}
|
||||
|
||||
arts = std::make_shared<CArtifactsOfHero>(Point(xOffset, yOffset), true);
|
||||
arts->recActions = 255-DISPOSE;
|
||||
arts->setHero(hero);
|
||||
arts->allowedAssembling = false;
|
||||
addSet(arts);
|
||||
|
||||
if(mode == EMarketMode::ARTIFACT_RESOURCE)
|
||||
arts->highlightModeCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
|
||||
{
|
||||
auto artifactsOfHero = std::make_shared<CArtifactsOfHeroMarket>(Point(xOffset, yOffset));
|
||||
artifactsOfHero->selectArtCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
|
||||
artifactsOfHero->setHero(hero);
|
||||
addSet(artifactsOfHero);
|
||||
arts = artifactsOfHero;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto artifactsOfHero = std::make_shared<CArtifactsOfHeroAltar>(Point(xOffset, yOffset));
|
||||
artifactsOfHero->setHero(hero);
|
||||
addSet(artifactsOfHero);
|
||||
arts = artifactsOfHero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -630,8 +640,8 @@ void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
|
||||
void CTradeWindow::artifactSelected(CHeroArtPlace *slot)
|
||||
{
|
||||
assert(mode == EMarketMode::ARTIFACT_RESOURCE);
|
||||
items[1][0]->setArtInstance(slot->ourArt);
|
||||
if(slot->ourArt && !slot->locked)
|
||||
items[1][0]->setArtInstance(slot->getArt());
|
||||
if(slot->getArt())
|
||||
hLeft = items[1][0];
|
||||
else
|
||||
hLeft = nullptr;
|
||||
@ -664,7 +674,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
madeTransaction = false;
|
||||
bool sliderNeeded = true;
|
||||
bool sliderNeeded = (mode != EMarketMode::RESOURCE_ARTIFACT && mode != EMarketMode::ARTIFACT_RESOURCE);
|
||||
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
|
||||
@ -679,7 +689,6 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
|
||||
break;
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
title = (*CGI->townh)[o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
|
||||
sliderNeeded = false;
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
title = (*CGI->townh)[o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
|
||||
@ -687,34 +696,15 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
|
||||
// create image that copies part of background containing slot MISC_1 into position of slot MISC_5
|
||||
// this is workaround for bug in H3 files where this slot for ragdoll on this screen is missing
|
||||
images.push_back(std::make_shared<CPicture>(background->getSurface(), Rect(20, 187, 47, 47), 18, 339 ));
|
||||
sliderNeeded = false;
|
||||
break;
|
||||
default:
|
||||
title = CGI->generaltexth->allTexts[158];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(auto * o = dynamic_cast<const CGMarket *>(market))
|
||||
{
|
||||
if(auto * o = dynamic_cast<const CGObjectInstance *>(market))
|
||||
{
|
||||
switch(o->ID)
|
||||
{
|
||||
case Obj::BLACK_MARKET:
|
||||
title = CGI->generaltexth->allTexts[349];
|
||||
sliderNeeded = false;
|
||||
break;
|
||||
case Obj::TRADING_POST:
|
||||
title = CGI->generaltexth->allTexts[159];
|
||||
break;
|
||||
case Obj::TRADING_POST_SNOW:
|
||||
title = CGI->generaltexth->allTexts[159];
|
||||
break;
|
||||
default:
|
||||
title = o->getObjectName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
title = o->title;
|
||||
}
|
||||
|
||||
titleLabel = std::make_shared<CLabel>(300, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title);
|
||||
@ -722,8 +712,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
|
||||
initItems(false);
|
||||
initItems(true);
|
||||
|
||||
ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[600], [&](){ close(); }, SDLK_RETURN);
|
||||
ok->assignedKeys.insert(SDLK_ESCAPE);
|
||||
ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[600], [&](){ close(); }, EShortcut::GLOBAL_RETURN);
|
||||
deal = std::make_shared<CButton>(Point(307, 520), "TPMRKB.DEF", CGI->generaltexth->zelp[595], [&](){ makeDeal(); } );
|
||||
deal->block(true);
|
||||
|
||||
@ -861,7 +850,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
|
||||
readyToTrade = readyToTrade && (hLeft->id != hRight->id); //for resource trade, two DIFFERENT resources must be selected
|
||||
|
||||
if(mode == EMarketMode::ARTIFACT_RESOURCE && !hLeft)
|
||||
arts->unmarkSlots(false);
|
||||
arts->unmarkSlots();
|
||||
|
||||
if(readyToTrade)
|
||||
{
|
||||
@ -1164,8 +1153,7 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero,
|
||||
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
|
||||
ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, SDLK_RETURN);
|
||||
ok->assignedKeys.insert(SDLK_ESCAPE);
|
||||
ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, EShortcut::GLOBAL_RETURN);
|
||||
|
||||
deal = std::make_shared<CButton>(Point(269, 520), "ALTSACR.DEF", CGI->generaltexth->zelp[585], std::bind(&CAltarWindow::makeDeal,this));
|
||||
|
||||
@ -1253,13 +1241,15 @@ void CAltarWindow::makeDeal()
|
||||
else
|
||||
{
|
||||
std::vector<ui32> positions;
|
||||
for(const CArtifactInstance *art : arts->artifactsOnAltar) //sacrifice each artifact on the list
|
||||
auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
|
||||
for(const CArtifactInstance * art : artifactsOfHero->artifactsOnAltar)
|
||||
{
|
||||
positions.push_back(hero->getArtPos(art));
|
||||
positions.push_back(hero->getSlotByInstance(art));
|
||||
}
|
||||
std::sort(positions.begin(), positions.end(), std::greater<>());
|
||||
|
||||
LOCPLINT->cb->trade(market, mode, positions, {}, {}, hero);
|
||||
arts->artifactsOnAltar.clear();
|
||||
artifactsOfHero->artifactsOnAltar.clear();
|
||||
|
||||
for(auto item : items[0])
|
||||
{
|
||||
@ -1267,7 +1257,6 @@ void CAltarWindow::makeDeal()
|
||||
item->subtitle = "";
|
||||
}
|
||||
|
||||
arts->commonInfo->reset();
|
||||
//arts->scrollBackpack(0);
|
||||
deal->block(true);
|
||||
}
|
||||
@ -1297,12 +1286,13 @@ void CAltarWindow::SacrificeAll()
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto i = hero->artifactsWorn.cbegin(); i != hero->artifactsWorn.cend(); i++)
|
||||
auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
|
||||
for(const auto & aw : artifactsOfHero->visibleArtSet.artifactsWorn)
|
||||
{
|
||||
if(!i->second.locked) //ignore locks from assembled artifacts
|
||||
moveFromSlotToAltar(i->first, nullptr, i->second.artifact);
|
||||
if(!aw.second.locked)
|
||||
moveArtToAltar(nullptr, aw.second.artifact);
|
||||
}
|
||||
|
||||
artifactsOfHero->updateWornSlots();
|
||||
SacrificeBackpack();
|
||||
}
|
||||
redraw();
|
||||
@ -1417,7 +1407,8 @@ void CAltarWindow::calcTotalExp()
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const CArtifactInstance *art : arts->artifactsOnAltar)
|
||||
auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
|
||||
for(const CArtifactInstance * art : artifactsOfHero->artifactsOnAltar)
|
||||
{
|
||||
int dmp, valOfArt;
|
||||
market->getOffer(art->artType->getId(), 0, dmp, valOfArt, mode);
|
||||
@ -1461,21 +1452,12 @@ int CAltarWindow::firstFreeSlot()
|
||||
|
||||
void CAltarWindow::SacrificeBackpack()
|
||||
{
|
||||
std::multiset<const CArtifactInstance *> toOmmit = arts->artifactsOnAltar;
|
||||
|
||||
for (auto & elem : hero->artifactsInBackpack)
|
||||
auto artsAltar = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
|
||||
while(!artsAltar->visibleArtSet.artifactsInBackpack.empty())
|
||||
{
|
||||
|
||||
if(vstd::contains(toOmmit, elem.artifact))
|
||||
{
|
||||
toOmmit -= elem.artifact;
|
||||
continue;
|
||||
}
|
||||
|
||||
putOnAltar(nullptr, elem.artifact);
|
||||
}
|
||||
|
||||
arts->scrollBackpack(0);
|
||||
if(!putOnAltar(nullptr, artsAltar->visibleArtSet.artifactsInBackpack[0].artifact))
|
||||
break;
|
||||
};
|
||||
calcTotalExp();
|
||||
}
|
||||
|
||||
@ -1487,15 +1469,18 @@ void CAltarWindow::artifactPicked()
|
||||
void CAltarWindow::showAll(SDL_Surface * to)
|
||||
{
|
||||
CTradeWindow::showAll(to);
|
||||
if(mode == EMarketMode::ARTIFACT_EXP && arts && arts->commonInfo->src.art)
|
||||
if(mode == EMarketMode::ARTIFACT_EXP && arts)
|
||||
{
|
||||
artIcon->setFrame(arts->commonInfo->src.art->artType->getIconIndex());
|
||||
artIcon->showAll(to);
|
||||
if(auto pickedArt = arts->getPickedArtifact())
|
||||
{
|
||||
artIcon->setFrame(pickedArt->artType->getIconIndex());
|
||||
artIcon->showAll(to);
|
||||
|
||||
int dmp, val;
|
||||
market->getOffer(arts->commonInfo->src.art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
|
||||
val = static_cast<int>(hero->calculateXp(val));
|
||||
printAtMiddleLoc(std::to_string(val), 304, 498, FONT_SMALL, Colors::WHITE, to);
|
||||
int dmp, val;
|
||||
market->getOffer(pickedArt->getTypeId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
|
||||
val = static_cast<int>(hero->calculateXp(val));
|
||||
printAtMiddleLoc(std::to_string(val), 304, 498, FONT_SMALL, Colors::WHITE, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1522,7 +1507,9 @@ bool CAltarWindow::putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const C
|
||||
market->getOffer(art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
|
||||
val = static_cast<int>(hero->calculateXp(val));
|
||||
|
||||
arts->artifactsOnAltar.insert(art);
|
||||
auto artsAltar = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
|
||||
artsAltar->artifactsOnAltar.insert(art);
|
||||
artsAltar->deleteFromVisible(art);
|
||||
altarSlot->setArtInstance(art);
|
||||
altarSlot->subtitle = std::to_string(val);
|
||||
|
||||
@ -1530,25 +1517,11 @@ bool CAltarWindow::putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const C
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAltarWindow::moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance *art)
|
||||
void CAltarWindow::moveArtToAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance *art)
|
||||
{
|
||||
auto freeBackpackSlot = ArtifactPosition((si32)hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START);
|
||||
if(arts->commonInfo->src.art)
|
||||
{
|
||||
arts->commonInfo->dst.slotID = freeBackpackSlot;
|
||||
arts->commonInfo->dst.AOH = arts.get();
|
||||
}
|
||||
|
||||
if(putOnAltar(altarSlot, art))
|
||||
{
|
||||
if(slotID < GameConstants::BACKPACK_START)
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero, slotID), ArtifactLocation(hero, freeBackpackSlot));
|
||||
else
|
||||
{
|
||||
arts->commonInfo->src.clear();
|
||||
arts->commonInfo->dst.clear();
|
||||
CCS->curh->dragAndDropCursor(nullptr);
|
||||
arts->unmarkSlots(false);
|
||||
}
|
||||
CCS->curh->dragAndDropCursor(nullptr);
|
||||
arts->unmarkSlots();
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../widgets/CArtifactHolder.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "CWindowObject.h"
|
||||
#include "../../lib/FunctionList.h"
|
||||
|
||||
@ -67,7 +67,7 @@ public:
|
||||
const IMarket * market;
|
||||
const CGHeroInstance * hero;
|
||||
|
||||
std::shared_ptr<CArtifactsOfHero> arts;
|
||||
std::shared_ptr<CArtifactsOfHeroBase> arts;
|
||||
//all indexes: 1 = left, 0 = right
|
||||
std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
|
||||
|
||||
@ -186,5 +186,5 @@ public:
|
||||
|
||||
void artifactPicked();
|
||||
int firstFreeSlot();
|
||||
void moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem>, const CArtifactInstance * art);
|
||||
void moveArtToAltar(std::shared_ptr<CTradeableItem>, const CArtifactInstance * art);
|
||||
};
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "CCreatureWindow.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
@ -32,12 +33,12 @@ void CreaturePurchaseCard::initButtons()
|
||||
|
||||
void CreaturePurchaseCard::initMaxButton()
|
||||
{
|
||||
maxButton = std::make_shared<CButton>(Point(pos.x + 52, pos.y + 180), "QuickRecruitmentWindow/QuickRecruitmentAllButton.def", CButton::tooltip(), std::bind(&CSlider::moveToMax,slider), SDLK_LSHIFT);
|
||||
maxButton = std::make_shared<CButton>(Point(pos.x + 52, pos.y + 180), "QuickRecruitmentWindow/QuickRecruitmentAllButton.def", CButton::tooltip(), std::bind(&CSlider::moveToMax,slider), EShortcut::RECRUITMENT_MAX);
|
||||
}
|
||||
|
||||
void CreaturePurchaseCard::initMinButton()
|
||||
{
|
||||
minButton = std::make_shared<CButton>(Point(pos.x, pos.y + 180), "QuickRecruitmentWindow/QuickRecruitmentNoneButton.def", CButton::tooltip(), std::bind(&CSlider::moveToMin,slider), SDLK_LCTRL);
|
||||
minButton = std::make_shared<CButton>(Point(pos.x, pos.y + 180), "QuickRecruitmentWindow/QuickRecruitmentNoneButton.def", CButton::tooltip(), std::bind(&CSlider::moveToMin,slider), EShortcut::RECRUITMENT_MIN);
|
||||
}
|
||||
|
||||
void CreaturePurchaseCard::initCreatureSwitcherButton()
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
@ -210,9 +211,9 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, c
|
||||
|
||||
slider = std::make_shared<CSlider>(Point(176,279),135,std::bind(&CRecruitmentWindow::sliderMoved,this, _1),0,0,0,true);
|
||||
|
||||
maxButton = std::make_shared<CButton>(Point(134, 313), "IRCBTNS.DEF", CGI->generaltexth->zelp[553], std::bind(&CSlider::moveToMax, slider), SDLK_m);
|
||||
buyButton = std::make_shared<CButton>(Point(212, 313), "IBY6432.DEF", CGI->generaltexth->zelp[554], std::bind(&CRecruitmentWindow::buy, this), SDLK_RETURN);
|
||||
cancelButton = std::make_shared<CButton>(Point(290, 313), "ICN6432.DEF", CGI->generaltexth->zelp[555], std::bind(&CRecruitmentWindow::close, this), SDLK_ESCAPE);
|
||||
maxButton = std::make_shared<CButton>(Point(134, 313), "IRCBTNS.DEF", CGI->generaltexth->zelp[553], std::bind(&CSlider::moveToMax, slider), EShortcut::RECRUITMENT_MAX);
|
||||
buyButton = std::make_shared<CButton>(Point(212, 313), "IBY6432.DEF", CGI->generaltexth->zelp[554], std::bind(&CRecruitmentWindow::buy, this), EShortcut::GLOBAL_ACCEPT);
|
||||
cancelButton = std::make_shared<CButton>(Point(290, 313), "ICN6432.DEF", CGI->generaltexth->zelp[555], std::bind(&CRecruitmentWindow::close, this), EShortcut::GLOBAL_CANCEL);
|
||||
|
||||
title = std::make_shared<CLabel>(243, 32, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW);
|
||||
availableValue = std::make_shared<CLabel>(205, 253, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
@ -313,8 +314,8 @@ CSplitWindow::CSplitWindow(const CCreature * creature, std::function<void(int, i
|
||||
int leftMax = total - rightMin;
|
||||
int rightMax = total - leftMin;
|
||||
|
||||
ok = std::make_shared<CButton>(Point(20, 263), "IOK6432", CButton::tooltip(), std::bind(&CSplitWindow::apply, this), SDLK_RETURN);
|
||||
cancel = std::make_shared<CButton>(Point(214, 263), "ICN6432", CButton::tooltip(), std::bind(&CSplitWindow::close, this), SDLK_ESCAPE);
|
||||
ok = std::make_shared<CButton>(Point(20, 263), "IOK6432", CButton::tooltip(), std::bind(&CSplitWindow::apply, this), EShortcut::GLOBAL_ACCEPT);
|
||||
cancel = std::make_shared<CButton>(Point(214, 263), "ICN6432", CButton::tooltip(), std::bind(&CSplitWindow::close, this), EShortcut::GLOBAL_CANCEL);
|
||||
|
||||
int sliderPosition = total - leftMin - rightMin;
|
||||
|
||||
@ -403,7 +404,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill::PrimarySki
|
||||
}
|
||||
|
||||
portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero->portrait, 0, 170, 66);
|
||||
ok = std::make_shared<CButton>(Point(297, 413), "IOKAY", CButton::tooltip(), std::bind(&CLevelWindow::close, this), SDLK_RETURN);
|
||||
ok = std::make_shared<CButton>(Point(297, 413), "IOKAY", CButton::tooltip(), std::bind(&CLevelWindow::close, this), EShortcut::GLOBAL_ACCEPT);
|
||||
|
||||
//%s has gained a level.
|
||||
mainTitle = std::make_shared<CLabel>(192, 33, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[444]) % hero->getNameTranslated()));
|
||||
@ -459,9 +460,9 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj)
|
||||
rumor = std::make_shared<CTextBox>(rumorText, Rect(32, 190, 330, 68), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
cancel = std::make_shared<CButton>(Point(310, 428), "ICANCEL.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[7]), std::bind(&CTavernWindow::close, this), SDLK_ESCAPE);
|
||||
recruit = std::make_shared<CButton>(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), SDLK_RETURN);
|
||||
thiefGuild = std::make_shared<CButton>(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), SDLK_t);
|
||||
cancel = std::make_shared<CButton>(Point(310, 428), "ICANCEL.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[7]), std::bind(&CTavernWindow::close, this), EShortcut::GLOBAL_CANCEL);
|
||||
recruit = std::make_shared<CButton>(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), EShortcut::GLOBAL_ACCEPT);
|
||||
thiefGuild = std::make_shared<CButton>(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), EShortcut::ADVENTURE_THIEVES_GUILD);
|
||||
|
||||
if(LOCPLINT->cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST) //not enough gold
|
||||
{
|
||||
@ -909,13 +910,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
portraits[0] = std::make_shared<CAnimImage>("PortraitsLarge", heroInst[0]->portrait, 0, 257, 13);
|
||||
portraits[1] = std::make_shared<CAnimImage>("PortraitsLarge", heroInst[1]->portrait, 0, 485, 13);
|
||||
|
||||
artifs[0] = std::make_shared<CArtifactsOfHero>(Point(-334, 150));
|
||||
artifs[0]->commonInfo = std::make_shared<CArtifactsOfHero::SCommonPart>();
|
||||
artifs[0]->commonInfo->participants.insert(artifs[0].get());
|
||||
artifs[0] = std::make_shared<CArtifactsOfHeroMain>(Point(-334, 150));
|
||||
artifs[0]->setHero(heroInst[0]);
|
||||
artifs[1] = std::make_shared<CArtifactsOfHero>(Point(96, 150));
|
||||
artifs[1]->commonInfo = artifs[0]->commonInfo;
|
||||
artifs[1]->commonInfo->participants.insert(artifs[1].get());
|
||||
artifs[1] = std::make_shared<CArtifactsOfHeroMain>(Point(98, 150));
|
||||
artifs[1]->setHero(heroInst[1]);
|
||||
|
||||
addSet(artifs[0]);
|
||||
@ -986,7 +983,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
luck[b] = std::make_shared<MoraleLuckBox>(false, Rect(Point(212 + 490 * b, 39), Point(32, 32)), true);
|
||||
}
|
||||
|
||||
quit = std::make_shared<CButton>(Point(732, 567), "IOKAY.DEF", CGI->generaltexth->zelp[600], std::bind(&CExchangeWindow::close, this), SDLK_RETURN);
|
||||
quit = std::make_shared<CButton>(Point(732, 567), "IOKAY.DEF", CGI->generaltexth->zelp[600], std::bind(&CExchangeWindow::close, this), EShortcut::GLOBAL_ACCEPT);
|
||||
if(queryID.getNum() > 0)
|
||||
quit->addCallback([=](){ LOCPLINT->cb->selectionMade(0, queryID); });
|
||||
|
||||
@ -1102,11 +1099,11 @@ CShipyardWindow::CShipyardWindow(const TResources & cost, int state, BoatId boat
|
||||
goldPic = std::make_shared<CAnimImage>("RESOURCE",GameResID(EGameResID::GOLD), 0, 100, 244);
|
||||
woodPic = std::make_shared<CAnimImage>("RESOURCE", GameResID(EGameResID::WOOD), 0, 196, 244);
|
||||
|
||||
quit = std::make_shared<CButton>(Point(224, 312), "ICANCEL", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CShipyardWindow::close, this), SDLK_ESCAPE);
|
||||
build = std::make_shared<CButton>(Point(42, 312), "IBUY30", CButton::tooltip(CGI->generaltexth->allTexts[598]), std::bind(&CShipyardWindow::close, this), SDLK_RETURN);
|
||||
quit = std::make_shared<CButton>(Point(224, 312), "ICANCEL", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_CANCEL);
|
||||
build = std::make_shared<CButton>(Point(42, 312), "IBUY30", CButton::tooltip(CGI->generaltexth->allTexts[598]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_ACCEPT);
|
||||
build->addCallback(onBuy);
|
||||
|
||||
for(auto i = EGameResID::WOOD; i <= EGameResID::GOLD; vstd::advance(i, 1))
|
||||
for(GameResID i = EGameResID::WOOD; i <= EGameResID::GOLD; ++i)
|
||||
{
|
||||
if(cost[i] > LOCPLINT->cb->getResourceAmount(i))
|
||||
{
|
||||
@ -1206,9 +1203,9 @@ CTransformerWindow::CTransformerWindow(const IMarket * _market, const CGHeroInst
|
||||
}
|
||||
}
|
||||
|
||||
all = std::make_shared<CButton>(Point(146, 416), "ALTARMY.DEF", CGI->generaltexth->zelp[590], [&](){ addAll(); }, SDLK_a);
|
||||
convert = std::make_shared<CButton>(Point(269, 416), "ALTSACR.DEF", CGI->generaltexth->zelp[591], [&](){ makeDeal(); }, SDLK_RETURN);
|
||||
cancel = std::make_shared<CButton>(Point(392, 416), "ICANCEL.DEF", CGI->generaltexth->zelp[592], [&](){ close(); },SDLK_ESCAPE);
|
||||
all = std::make_shared<CButton>(Point(146, 416), "ALTARMY.DEF", CGI->generaltexth->zelp[590], [&](){ addAll(); }, EShortcut::RECRUITMENT_UPGRADE_ALL);
|
||||
convert = std::make_shared<CButton>(Point(269, 416), "ALTSACR.DEF", CGI->generaltexth->zelp[591], [&](){ makeDeal(); }, EShortcut::GLOBAL_ACCEPT);
|
||||
cancel = std::make_shared<CButton>(Point(392, 416), "ICANCEL.DEF", CGI->generaltexth->zelp[592], [&](){ close(); },EShortcut::GLOBAL_CANCEL);
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
|
||||
titleLeft = std::make_shared<CLabel>(153, 29,FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[485]);//holding area
|
||||
@ -1321,12 +1318,11 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
|
||||
title = std::make_shared<CLabel>(231, 26, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, titleStr);
|
||||
|
||||
std::vector<int> goods = market->availableItemsIds(EMarketMode::RESOURCE_SKILL);
|
||||
assert(goods.size() == 4);
|
||||
|
||||
for(int i=0; i<goods.size(); i++)//prepare clickable items
|
||||
items.push_back(std::make_shared<CItem>(this, goods[i], 54+i*104, 234));
|
||||
|
||||
cancel = std::make_shared<CButton>(Point(200, 313), "IOKAY.DEF", CGI->generaltexth->zelp[632], [&](){ close(); }, SDLK_RETURN);
|
||||
cancel = std::make_shared<CButton>(Point(200, 313), "IOKAY.DEF", CGI->generaltexth->zelp[632], [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
}
|
||||
|
||||
@ -1364,10 +1360,10 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo
|
||||
boost::replace_first(text, "%s", CGI->skillh->getByIndex(SKILL)->getNameTranslated());
|
||||
boost::replace_first(text, "%d", "2000");
|
||||
|
||||
confirm = std::make_shared<CButton>(Point(148, 299), "IBY6432.DEF", CButton::tooltip(hoverText, text), [=](){makeDeal(SKILL);}, SDLK_RETURN);
|
||||
confirm = std::make_shared<CButton>(Point(148, 299), "IBY6432.DEF", CButton::tooltip(hoverText, text), [=](){makeDeal(SKILL);}, EShortcut::GLOBAL_ACCEPT);
|
||||
confirm->block(!available);
|
||||
|
||||
cancel = std::make_shared<CButton>(Point(252,299), "ICANCEL.DEF", CGI->generaltexth->zelp[631], [&](){ close(); }, SDLK_ESCAPE);
|
||||
cancel = std::make_shared<CButton>(Point(252,299), "ICANCEL.DEF", CGI->generaltexth->zelp[631], [&](){ close(); }, EShortcut::GLOBAL_CANCEL);
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
}
|
||||
|
||||
@ -1387,7 +1383,7 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance
|
||||
auto split = std::make_shared<CButton>(Point(88, 314), "IDV6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); } );
|
||||
garr->addSplitBtn(split);
|
||||
}
|
||||
quit = std::make_shared<CButton>(Point(399, 314), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&](){ close(); }, SDLK_RETURN);
|
||||
quit = std::make_shared<CButton>(Point(399, 314), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);
|
||||
|
||||
std::string titleText;
|
||||
if(down->tempOwner == up->tempOwner)
|
||||
@ -1437,7 +1433,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI
|
||||
|
||||
for(int i = 0; i < slotsCount; i++)
|
||||
{
|
||||
upgrade[i] = std::make_shared<CButton>(Point(107 + i * 76, 171), "", CButton::tooltip(getTextForSlot(SlotID(i))), [=](){ makeDeal(SlotID(i)); }, SDLK_1 + i);
|
||||
upgrade[i] = std::make_shared<CButton>(Point(107 + i * 76, 171), "", CButton::tooltip(getTextForSlot(SlotID(i))), [=](){ makeDeal(SlotID(i)); }, vstd::next(EShortcut::SELECT_INDEX_1, i));
|
||||
for(auto image : { "APHLF1R.DEF", "APHLF1Y.DEF", "APHLF1G.DEF" })
|
||||
upgrade[i]->addImage(image);
|
||||
|
||||
@ -1448,11 +1444,11 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI
|
||||
}
|
||||
}
|
||||
|
||||
upgradeAll = std::make_shared<CButton>(Point(30, 231), "", CButton::tooltip(CGI->generaltexth->allTexts[432]), [&](){ makeDeal(SlotID(slotsCount));}, SDLK_0);
|
||||
upgradeAll = std::make_shared<CButton>(Point(30, 231), "", CButton::tooltip(CGI->generaltexth->allTexts[432]), [&](){ makeDeal(SlotID(slotsCount));}, EShortcut::RECRUITMENT_UPGRADE_ALL);
|
||||
for(auto image : { "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF" })
|
||||
upgradeAll->addImage(image);
|
||||
|
||||
quit = std::make_shared<CButton>(Point(294, 275), "IOKAY.DEF", CButton::tooltip(), std::bind(&CHillFortWindow::close, this), SDLK_RETURN);
|
||||
quit = std::make_shared<CButton>(Point(294, 275), "IOKAY.DEF", CButton::tooltip(), std::bind(&CHillFortWindow::close, this), EShortcut::GLOBAL_ACCEPT);
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
|
||||
garr = std::make_shared<CGarrisonInt>(108, 60, 18, Point(), hero, nullptr);
|
||||
@ -1628,8 +1624,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
|
||||
SThievesGuildInfo tgi; //info to be displayed
|
||||
LOCPLINT->cb->getThievesGuildInfo(tgi, owner);
|
||||
|
||||
exitb = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(CGI->generaltexth->allTexts[600]), [&](){ close();}, SDLK_RETURN);
|
||||
exitb->assignedKeys.insert(SDLK_ESCAPE);
|
||||
exitb = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(CGI->generaltexth->allTexts[600]), [&](){ close();}, EShortcut::GLOBAL_RETURN);
|
||||
statusbar = CGStatusBar::create(3, 555, "TStatBar.bmp", 742);
|
||||
|
||||
resdatabar = std::make_shared<CMinorResDataBar>();
|
||||
@ -1825,7 +1820,7 @@ void CObjectListWindow::init(std::shared_ptr<CIntObject> titleWidget_, std::stri
|
||||
|
||||
title = std::make_shared<CLabel>(152, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, _title);
|
||||
descr = std::make_shared<CLabel>(145, 133, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, _descr);
|
||||
exit = std::make_shared<CButton>( Point(228, 402), "ICANCEL.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::exitPressed, this), SDLK_ESCAPE);
|
||||
exit = std::make_shared<CButton>( Point(228, 402), "ICANCEL.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::exitPressed, this), EShortcut::GLOBAL_CANCEL);
|
||||
|
||||
if(titleWidget)
|
||||
{
|
||||
@ -1838,7 +1833,7 @@ void CObjectListWindow::init(std::shared_ptr<CIntObject> titleWidget_, std::stri
|
||||
Point(14, 151), Point(0, 25), 9, items.size(), 0, 1, Rect(262, -32, 256, 256) );
|
||||
list->type |= REDRAW_PARENT;
|
||||
|
||||
ok = std::make_shared<CButton>(Point(15, 402), "IOKAY.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::elementSelected, this), SDLK_RETURN);
|
||||
ok = std::make_shared<CButton>(Point(15, 402), "IOKAY.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::elementSelected, this), EShortcut::GLOBAL_ACCEPT);
|
||||
ok->block(!list->size());
|
||||
}
|
||||
|
||||
@ -1886,28 +1881,28 @@ void CObjectListWindow::changeSelection(size_t which)
|
||||
selected = which;
|
||||
}
|
||||
|
||||
void CObjectListWindow::keyPressed (const SDL_Keycode & key)
|
||||
void CObjectListWindow::keyPressed (EShortcut key)
|
||||
{
|
||||
int sel = static_cast<int>(selected);
|
||||
|
||||
switch(key)
|
||||
{
|
||||
break; case SDLK_UP:
|
||||
break; case EShortcut::MOVE_UP:
|
||||
sel -=1;
|
||||
|
||||
break; case SDLK_DOWN:
|
||||
break; case EShortcut::MOVE_DOWN:
|
||||
sel +=1;
|
||||
|
||||
break; case SDLK_PAGEUP:
|
||||
break; case EShortcut::MOVE_PAGE_UP:
|
||||
sel -=9;
|
||||
|
||||
break; case SDLK_PAGEDOWN:
|
||||
break; case EShortcut::MOVE_PAGE_DOWN:
|
||||
sel +=9;
|
||||
|
||||
break; case SDLK_HOME:
|
||||
break; case EShortcut::MOVE_FIRST:
|
||||
sel = 0;
|
||||
|
||||
break; case SDLK_END:
|
||||
break; case EShortcut::MOVE_LAST:
|
||||
sel = static_cast<int>(items.size());
|
||||
|
||||
break; default:
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "../lib/ResourceSet.h"
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "../lib/int3.h"
|
||||
#include "../widgets/CArtifactHolder.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "../widgets/CGarrisonInt.h"
|
||||
#include "../widgets/Images.h"
|
||||
|
||||
@ -194,7 +194,7 @@ public:
|
||||
std::shared_ptr<CIntObject> genItem(size_t index);
|
||||
void elementSelected();//call callback and close this window
|
||||
void changeSelection(size_t which);
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
};
|
||||
|
||||
class CTavernWindow : public CStatusbarWindow
|
||||
@ -327,7 +327,7 @@ class CExchangeWindow : public CStatusbarWindow, public CGarrisonHolder, public
|
||||
|
||||
public:
|
||||
std::array<const CGHeroInstance *, 2> heroInst;
|
||||
std::array<std::shared_ptr<CArtifactsOfHero>, 2> artifs;
|
||||
std::array<std::shared_ptr<CArtifactsOfHeroMain>, 2> artifs;
|
||||
|
||||
void updateGarrisons() override;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
@ -79,9 +80,6 @@ CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperl
|
||||
|
||||
text = std::make_shared<CTextBox>(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE);
|
||||
|
||||
buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter
|
||||
buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape
|
||||
|
||||
if (buttons.size() > 1 && askID.getNum() >= 0) //cancel button functionality
|
||||
{
|
||||
buttons.back()->addCallback([askID]() {
|
||||
@ -96,8 +94,8 @@ CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperl
|
||||
addChild(comps[i].get());
|
||||
components.push_back(comps[i]);
|
||||
comps[i]->onSelect = std::bind(&CSelWindow::selectionChange,this,i);
|
||||
if(i<9)
|
||||
comps[i]->assignedKeys.insert(SDLK_1+i);
|
||||
if(i<8)
|
||||
comps[i]->assignedKey = vstd::next(EShortcut::SELECT_INDEX_1,i);
|
||||
}
|
||||
CMessage::drawIWindow(this, Text, player);
|
||||
}
|
||||
@ -137,10 +135,13 @@ CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo
|
||||
text->resize(text->label->textSize);
|
||||
}
|
||||
|
||||
if(buttons.size())
|
||||
if(buttons.size() == 1)
|
||||
buttons.front()->assignedKey = EShortcut::GLOBAL_RETURN;
|
||||
|
||||
if(buttons.size() == 2)
|
||||
{
|
||||
buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter
|
||||
buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape
|
||||
buttons.front()->assignedKey = EShortcut::GLOBAL_ACCEPT;
|
||||
buttons.back()->assignedKey = EShortcut::GLOBAL_CANCEL;
|
||||
}
|
||||
|
||||
for(auto & comp : comps)
|
||||
|
@ -45,8 +45,8 @@ public:
|
||||
class CInfoWindow : public CSimpleWindow
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::pair<std::string, CFunctionList<void()> > > TButtonsInfo;
|
||||
typedef std::vector<std::shared_ptr<CComponent>> TCompsInfo;
|
||||
using TButtonsInfo = std::vector<std::pair<std::string, CFunctionList<void()>>>;
|
||||
using TCompsInfo = std::vector<std::shared_ptr<CComponent>>;
|
||||
QueryID ID; //for identification
|
||||
std::shared_ptr<CTextBox> text;
|
||||
std::vector<std::shared_ptr<CButton>> buttons;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/CreatureCostBox.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/ResourceSet.h"
|
||||
#include "../../lib/CCreatureHandler.h"
|
||||
@ -29,20 +30,19 @@ void QuickRecruitmentWindow::setButtons()
|
||||
|
||||
void QuickRecruitmentWindow::setCancelButton()
|
||||
{
|
||||
cancelButton = std::make_shared<CButton>(Point((pos.w / 2) + 48, 418), "ICN6432.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_ESCAPE);
|
||||
cancelButton = std::make_shared<CButton>(Point((pos.w / 2) + 48, 418), "ICN6432.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::GLOBAL_CANCEL);
|
||||
cancelButton->setImageOrder(0, 1, 2, 3);
|
||||
}
|
||||
|
||||
void QuickRecruitmentWindow::setBuyButton()
|
||||
{
|
||||
buyButton = std::make_shared<CButton>(Point((pos.w / 2) - 32, 418), "IBY6432.DEF", CButton::tooltip(), [&](){ purchaseUnits(); }, SDLK_RETURN);
|
||||
cancelButton->assignedKeys.insert(SDLK_ESCAPE);
|
||||
buyButton = std::make_shared<CButton>(Point((pos.w / 2) - 32, 418), "IBY6432.DEF", CButton::tooltip(), [&](){ purchaseUnits(); }, EShortcut::GLOBAL_ACCEPT);
|
||||
buyButton->setImageOrder(0, 1, 2, 3);
|
||||
}
|
||||
|
||||
void QuickRecruitmentWindow::setMaxButton()
|
||||
{
|
||||
maxButton = std::make_shared<CButton>(Point((pos.w/2)-112, 418), "IRCBTNS.DEF", CButton::tooltip(), [&](){ maxAllCards(cards); }, SDLK_m);
|
||||
maxButton = std::make_shared<CButton>(Point((pos.w/2)-112, 418), "IRCBTNS.DEF", CButton::tooltip(), [&](){ maxAllCards(cards); }, EShortcut::RECRUITMENT_MAX);
|
||||
maxButton->setImageOrder(0, 1, 2, 3);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"roe" :
|
||||
{
|
||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPBACK"} ],
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/GOOD1.H3C", "image":"CAMPGD1S", "video":"CGOOD1", "open": true },
|
||||
@ -22,7 +22,7 @@
|
||||
{"x": 34, "y": 417, "name":"CAMP1FWX"},//one campaign have special inactive image
|
||||
{"x": 385, "y": 401, "name":"CAMPNOSC"},//and the last one is not present
|
||||
],
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/AB.H3C", "image":"CAMP1AB7", "video":"C1ab7", "open": true },
|
||||
@ -36,7 +36,7 @@
|
||||
"sod":
|
||||
{
|
||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPBKX2"} ],
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/GEM.H3C", "image":"CAMPNB1", "video":"NEW", "open": true },
|
||||
@ -47,18 +47,18 @@
|
||||
{ "x":34, "y":417, "file":"DATA/FINAL.H3C", "image":"CAMPUA1", "video":"UNHOLY", "open": true },
|
||||
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
|
||||
]
|
||||
},
|
||||
"wog" :
|
||||
{
|
||||
/// wog campaigns, currently has no assigned button in campaign screen and thus unused
|
||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/ZC1.H3C", "image":"CAMPZ01", "open": true},
|
||||
{ "x":539, "y":72, "file":"DATA/ZC2.H3C", "image":"CAMPZ02", "open": true},
|
||||
{ "x":43, "y":245, "file":"DATA/ZC3.H3C", "image":"CAMPZ03", "open": true},
|
||||
{ "x":311, "y":242, "file":"DATA/ZC4.H3C", "image":"CAMPZ04", "open": true}
|
||||
]
|
||||
}
|
||||
// "wog" :
|
||||
// {
|
||||
// /// wog campaigns, currently has no assigned button in campaign screen and thus unused
|
||||
// "images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
|
||||
// "exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
// "items":
|
||||
// [
|
||||
// { "x":90, "y":72, "file":"DATA/ZC1.H3C", "image":"CAMPZ01", "open": true},
|
||||
// { "x":539, "y":72, "file":"DATA/ZC2.H3C", "image":"CAMPZ02", "open": true},
|
||||
// { "x":43, "y":245, "file":"DATA/ZC3.H3C", "image":"CAMPZ03", "open": true},
|
||||
// { "x":311, "y":242, "file":"DATA/ZC4.H3C", "image":"CAMPZ04", "open": true}
|
||||
// ]
|
||||
// }
|
||||
}
|
||||
|
@ -17,22 +17,22 @@
|
||||
"name" : "main",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 644, "y": 70, "center" : true, "name":"MMENUNG", "hotkey" : 110, "help": 3, "command": "to new"},
|
||||
{"x": 645, "y": 192, "center" : true, "name":"MMENULG", "hotkey" : 108, "help": 4, "command": "to load"},
|
||||
{"x": 643, "y": 296, "center" : true, "name":"MMENUHS", "hotkey" : 104, "help": 5, "command": "highscores"},
|
||||
{"x": 643, "y": 414, "center" : true, "name":"MMENUCR", "hotkey" : 99, "help": 6, "command": "to credits"},
|
||||
{"x": 643, "y": 520, "center" : true, "name":"MMENUQT", "hotkey" : 27, "help": 7, "command": "exit"}
|
||||
{"x": 644, "y": 70, "center" : true, "name":"MMENUNG", "shortcut" : "mainMenuNew", "help": 3, "command": "to new"},
|
||||
{"x": 645, "y": 192, "center" : true, "name":"MMENULG", "shortcut" : "mainMenuLoad", "help": 4, "command": "to load"},
|
||||
{"x": 643, "y": 296, "center" : true, "name":"MMENUHS", "shortcut" : "mainMenuScores", "help": 5, "command": "highscores"},
|
||||
{"x": 643, "y": 414, "center" : true, "name":"MMENUCR", "shortcut" : "mainMenuCredits", "help": 6, "command": "to credits"},
|
||||
{"x": 643, "y": 520, "center" : true, "name":"MMENUQT", "shortcut" : "mainMenuQuit", "help": 7, "command": "exit"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "new",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 649, "y": 65, "center" : true, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "start single"},
|
||||
{"x": 649, "y": 180, "center" : true, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "start multi"},
|
||||
{"x": 646, "y": 298, "center" : true, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "to campaign"},
|
||||
{"x": 647, "y": 412, "center" : true, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"},
|
||||
{"x": 645, "y": 517, "center" : true, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
|
||||
{"x": 649, "y": 65, "center" : true, "name":"GTSINGL", "shortcut" : "mainMenuSingleplayer", "help": 10, "command": "start single"},
|
||||
{"x": 649, "y": 180, "center" : true, "name":"GTMULTI", "shortcut" : "mainMenuMultiplayer", "help": 12, "command": "start multi"},
|
||||
{"x": 646, "y": 298, "center" : true, "name":"GTCAMPN", "shortcut" : "mainMenuCampaign", "help": 11, "command": "to campaign"},
|
||||
{"x": 647, "y": 412, "center" : true, "name":"GTTUTOR", "shortcut" : "mainMenuTutorial", "help": 13, "command": "start tutorial"},
|
||||
{"x": 645, "y": 517, "center" : true, "name":"GTBACK", "shortcut" : "mainMenuBack", "help": 14, "command": "to main"}
|
||||
],
|
||||
"images": [ {"x": 114, "y": 312, "name":"NEWGAME"} ]
|
||||
},
|
||||
@ -40,11 +40,11 @@
|
||||
"name" : "load",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 649, "y": 65, "center" : true, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "load single"},
|
||||
{"x": 649, "y": 180, "center" : true, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "load multi"},
|
||||
{"x": 646, "y": 298, "center" : true, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "load campaign"},
|
||||
{"x": 647, "y": 412, "center" : true, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"},
|
||||
{"x": 645, "y": 517, "center" : true, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
|
||||
{"x": 649, "y": 65, "center" : true, "name":"GTSINGL", "shortcut" : "mainMenuSingleplayer", "help": 10, "command": "load single"},
|
||||
{"x": 649, "y": 180, "center" : true, "name":"GTMULTI", "shortcut" : "mainMenuMultiplayer", "help": 12, "command": "load multi"},
|
||||
{"x": 646, "y": 298, "center" : true, "name":"GTCAMPN", "shortcut" : "mainMenuCampaign", "help": 11, "command": "load campaign"},
|
||||
{"x": 647, "y": 412, "center" : true, "name":"GTTUTOR", "shortcut" : "mainMenuTutorial", "help": 13, "command": "load tutorial"},
|
||||
{"x": 645, "y": 517, "center" : true, "name":"GTBACK", "shortcut" : "mainMenuBack", "help": 14, "command": "to main"}
|
||||
],
|
||||
"images": [ {"x": 114, "y": 312, "name":"LOADGAME"} ]
|
||||
},
|
||||
@ -52,11 +52,11 @@
|
||||
"name" : "campaign",
|
||||
"buttons":
|
||||
[
|
||||
{"x": 634, "y": 67, "center" : true, "name":"CSSSOD", "hotkey" : 119, "command": "campaigns sod"},
|
||||
{"x": 637, "y": 181, "center" : true, "name":"CSSROE", "hotkey" : 114, "command": "campaigns roe"},
|
||||
{"x": 638, "y": 301, "center" : true, "name":"CSSARM", "hotkey" : 97, "command": "campaigns ab"},
|
||||
{"x": 638, "y": 413, "center" : true, "name":"CSSCUS", "hotkey" : 99, "command": "start campaign"},
|
||||
{"x": 639, "y": 518, "center" : true, "name":"CSSEXIT", "hotkey" : 27, "command": "to new"}
|
||||
{"x": 634, "y": 67, "center" : true, "name":"CSSSOD", "shortcut" : "mainMenuCampaignSod", "command": "campaigns sod"},
|
||||
{"x": 637, "y": 181, "center" : true, "name":"CSSROE", "shortcut" : "mainMenuCampaignRoe", "command": "campaigns roe"},
|
||||
{"x": 638, "y": 301, "center" : true, "name":"CSSARM", "shortcut" : "mainMenuCampaignAb", "command": "campaigns ab"},
|
||||
{"x": 638, "y": 413, "center" : true, "name":"CSSCUS", "shortcut" : "mainMenuCampaign", "command": "start campaign"},
|
||||
{"x": 639, "y": 518, "center" : true, "name":"CSSEXIT", "shortcut" : "mainMenuBack", "command": "to new"}
|
||||
],
|
||||
}
|
||||
]
|
||||
|
@ -15,7 +15,7 @@
|
||||
},
|
||||
|
||||
"altarOfSacrifice" : {
|
||||
"index" :2,
|
||||
"index" :2,
|
||||
"handler" : "market",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
@ -36,7 +36,7 @@
|
||||
}
|
||||
},
|
||||
"tradingPost" : {
|
||||
"index" :221,
|
||||
"index" :221,
|
||||
"handler" : "market",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
@ -54,12 +54,13 @@
|
||||
"rarity" : 100
|
||||
},
|
||||
"modes" : ["resource-resource", "resource-player"],
|
||||
"efficacy" : 5
|
||||
"efficiency" : 5,
|
||||
"title" : "core.genrltxt.159"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tradingPostDUPLICATE" : {
|
||||
"index" :99,
|
||||
"index" :99,
|
||||
"handler" : "market",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
@ -77,12 +78,13 @@
|
||||
"rarity" : 100
|
||||
},
|
||||
"modes" : ["resource-resource", "resource-player"],
|
||||
"efficacy" : 5
|
||||
"efficiency" : 5,
|
||||
"title" : "core.genrltxt.159"
|
||||
}
|
||||
}
|
||||
},
|
||||
"freelancersGuild" : {
|
||||
"index" :213,
|
||||
"index" :213,
|
||||
"handler" : "market",
|
||||
"types" : {
|
||||
"object" : {
|
||||
@ -99,7 +101,7 @@
|
||||
},
|
||||
|
||||
"blackMarket" : {
|
||||
"index" :7,
|
||||
"index" :7,
|
||||
"handler" : "market",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
@ -115,7 +117,8 @@
|
||||
"value" : 8000,
|
||||
"rarity" : 20
|
||||
},
|
||||
"modes" : ["resource-artifact"]
|
||||
"modes" : ["resource-artifact"],
|
||||
"title" : "core.genrltxt.349"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -542,7 +545,7 @@
|
||||
}
|
||||
},
|
||||
"university" : {
|
||||
"index" :104,
|
||||
"index" :104,
|
||||
"handler" : "market",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
@ -559,7 +562,14 @@
|
||||
},
|
||||
"modes" : ["resource-skill"],
|
||||
"title" : "core.genrltxt.602",
|
||||
"speech" : "core.genrltxt.603"
|
||||
"speech" : "core.genrltxt.603",
|
||||
"offer":
|
||||
[
|
||||
{ "noneOf" : ["necromancy"] },
|
||||
{ "noneOf" : ["necromancy"] },
|
||||
{ "noneOf" : ["necromancy"] },
|
||||
{ "noneOf" : ["necromancy"] }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -21,8 +21,7 @@
|
||||
"position": {"x": 4, "y": 560},
|
||||
"image": "icm003",
|
||||
"help": "core.help.381",
|
||||
"callback": "options",
|
||||
"hotkey": "o"
|
||||
"hotkey": "globalOptions"
|
||||
},
|
||||
|
||||
{
|
||||
@ -31,8 +30,7 @@
|
||||
"position": {"x": 55, "y": 560},
|
||||
"image": "icm001",
|
||||
"help": "core.help.379",
|
||||
"callback": "surrender",
|
||||
"hotkey": "s"
|
||||
"hotkey": "battleSurrender"
|
||||
},
|
||||
|
||||
{
|
||||
@ -41,8 +39,7 @@
|
||||
"position": {"x": 106, "y": 560},
|
||||
"image": "icm002",
|
||||
"help": "core.help.380",
|
||||
"callback": "flee",
|
||||
"hotkey": "r"
|
||||
"hotkey": "battleRetreat"
|
||||
},
|
||||
|
||||
{
|
||||
@ -51,8 +48,7 @@
|
||||
"position": {"x": 157, "y": 560},
|
||||
"image": "icm004",
|
||||
"help": "core.help.382",
|
||||
"callback": "autofight",
|
||||
"hotkey": "a"
|
||||
"hotkey": "battleAutocombat"
|
||||
},
|
||||
|
||||
{
|
||||
@ -61,8 +57,7 @@
|
||||
"position": {"x": 646, "y": 560},
|
||||
"image": "icm005",
|
||||
"help": "core.help.385",
|
||||
"callback": "spellbook",
|
||||
"hotkey": "c"
|
||||
"hotkey": "battleCastSpell"
|
||||
},
|
||||
|
||||
{
|
||||
@ -71,8 +66,7 @@
|
||||
"position": {"x": 697, "y": 560},
|
||||
"image": "icm006",
|
||||
"help": "core.help.386",
|
||||
"callback": "wait",
|
||||
"hotkey": "w"
|
||||
"hotkey": "battleWait"
|
||||
},
|
||||
|
||||
{
|
||||
@ -81,8 +75,7 @@
|
||||
"position": {"x": 748, "y": 560},
|
||||
"image": "icm007",
|
||||
"help": "core.help.387",
|
||||
"callback": "defence",
|
||||
"hotkey": ["d", "space"]
|
||||
"hotkey": "battleDefend"
|
||||
},
|
||||
|
||||
{
|
||||
@ -90,9 +83,8 @@
|
||||
"name": "consoleUp",
|
||||
"position": {"x": 625, "y": 560},
|
||||
"image": "ComSlide",
|
||||
"callback": "consoleUp",
|
||||
"imageOrder": [0, 1, 0, 0],
|
||||
"hotkey": "up"
|
||||
"hotkey": "battleConsoleUp"
|
||||
},
|
||||
|
||||
{
|
||||
@ -100,9 +92,8 @@
|
||||
"name": "consoleDown",
|
||||
"position": {"x": 625, "y": 579},
|
||||
"image": "ComSlide",
|
||||
"callback": "consoleDown",
|
||||
"imageOrder": [2, 3, 2, 2],
|
||||
"hotkey": "down"
|
||||
"hotkey": "battleConsoleDown"
|
||||
},
|
||||
|
||||
{
|
||||
@ -117,8 +108,7 @@
|
||||
"name": "tacticNext",
|
||||
"position": {"x": 213, "y": 560},
|
||||
"image": "icm011",
|
||||
"callback": "tacticNext",
|
||||
"hotkey": "space"
|
||||
"hotkey": "battleTacticsNext"
|
||||
},
|
||||
|
||||
{
|
||||
@ -126,8 +116,7 @@
|
||||
"name": "tacticEnd",
|
||||
"position": {"x": 419, "y": 560},
|
||||
"image": "icm012",
|
||||
"callback": "tacticEnd",
|
||||
"hotkey": "enter"
|
||||
"hotkey": "battleTacticsEnd"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -47,7 +47,6 @@
|
||||
"image": "settingsWindow/button32",
|
||||
"help": "vcmi.systemOptions.resolutionButton",
|
||||
"callback": "setGameResolution",
|
||||
"hotkey": "g",
|
||||
"items":
|
||||
[
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user