mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
Use variant identifier in netpacks where applicable
This commit is contained in:
parent
63e99a32d7
commit
6b81012f31
@ -481,7 +481,7 @@ void AIGateway::objectPropertyChanged(const SetObjectProperty * sop)
|
||||
NET_EVENT_HANDLER;
|
||||
if(sop->what == ObjProperty::OWNER)
|
||||
{
|
||||
auto relations = myCb->getPlayerRelations(playerID, (PlayerColor)sop->val);
|
||||
auto relations = myCb->getPlayerRelations(playerID, sop->identifier.as<PlayerColor>());
|
||||
auto obj = myCb->getObj(sop->id, false);
|
||||
|
||||
if(!nullkiller) // crash protection
|
||||
@ -1419,7 +1419,7 @@ void AIGateway::tryRealize(Goals::Trade & g) //trade
|
||||
//TODO trade only as much as needed
|
||||
if (toGive) //don't try to sell 0 resources
|
||||
{
|
||||
cb->trade(m, EMarketMode::RESOURCE_RESOURCE, res, g.resID, toGive);
|
||||
cb->trade(m, EMarketMode::RESOURCE_RESOURCE, res, GameResID(g.resID), toGive);
|
||||
accquiredResources = static_cast<int>(toGet * (it->resVal / toGive));
|
||||
logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, accquiredResources, g.resID, obj->getObjectName());
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
|
||||
NET_EVENT_HANDLER;
|
||||
if(sop->what == ObjProperty::OWNER)
|
||||
{
|
||||
if(myCb->getPlayerRelations(playerID, (PlayerColor)sop->val) == PlayerRelations::ENEMIES)
|
||||
if(myCb->getPlayerRelations(playerID, sop->identifier.as<PlayerColor>()) == PlayerRelations::ENEMIES)
|
||||
{
|
||||
//we want to visit objects owned by oppponents
|
||||
auto obj = myCb->getObj(sop->id, false);
|
||||
@ -2160,7 +2160,7 @@ void VCAI::tryRealize(Goals::Trade & g) //trade
|
||||
//TODO trade only as much as needed
|
||||
if (toGive) //don't try to sell 0 resources
|
||||
{
|
||||
cb->trade(m, EMarketMode::RESOURCE_RESOURCE, res, g.resID, toGive);
|
||||
cb->trade(m, EMarketMode::RESOURCE_RESOURCE, res, GameResID(g.resID), toGive);
|
||||
accquiredResources = static_cast<int>(toGet * (it->resVal / toGive));
|
||||
logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, accquiredResources, g.resID, obj->getObjectName());
|
||||
}
|
||||
|
@ -237,12 +237,12 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID aid)
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
void CCallback::trade(const IMarket * market, EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero)
|
||||
void CCallback::trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero)
|
||||
{
|
||||
trade(market, mode, std::vector<ui32>(1, id1), std::vector<ui32>(1, id2), std::vector<ui32>(1, val1), hero);
|
||||
trade(market, mode, std::vector(1, id1), std::vector(1, id2), std::vector(1, val1), hero);
|
||||
}
|
||||
|
||||
void CCallback::trade(const IMarket * market, EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero)
|
||||
void CCallback::trade(const IMarket * market, EMarketMode mode, const std::vector<TradeItemSell> & id1, const std::vector<TradeItemBuy> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero)
|
||||
{
|
||||
TradeOnMarketplace pack;
|
||||
pack.marketId = dynamic_cast<const CGObjectInstance *>(market)->id;
|
||||
@ -254,9 +254,9 @@ void CCallback::trade(const IMarket * market, EMarketMode mode, const std::vecto
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
|
||||
void CCallback::setFormation(const CGHeroInstance * hero, EArmyFormation mode)
|
||||
{
|
||||
SetFormation pack(hero->id,tight);
|
||||
SetFormation pack(hero->id, mode);
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
|
13
CCallback.h
13
CCallback.h
@ -12,6 +12,7 @@
|
||||
#include "lib/CGameInfoCallback.h"
|
||||
#include "lib/battle/CPlayerBattleCallback.h"
|
||||
#include "lib/int3.h" // for int3
|
||||
#include "lib/networkPacks/TradeItem.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -78,8 +79,8 @@ public:
|
||||
virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
|
||||
virtual void swapGarrisonHero(const CGTownInstance *town)=0;
|
||||
|
||||
virtual void trade(const IMarket * market, EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
|
||||
virtual void trade(const IMarket * market, EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr)=0;
|
||||
virtual void trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
|
||||
virtual void trade(const IMarket * market, EMarketMode mode, const std::vector<TradeItemSell> & id1, const std::vector<TradeItemBuy> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr)=0;
|
||||
|
||||
virtual int selectionMade(int selection, QueryID queryID) =0;
|
||||
virtual int sendQueryReply(std::optional<int32_t> reply, QueryID queryID) =0;
|
||||
@ -94,7 +95,7 @@ public:
|
||||
virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0;
|
||||
virtual void endTurn()=0;
|
||||
virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
|
||||
virtual void setFormation(const CGHeroInstance * hero, bool tight)=0;
|
||||
virtual void setFormation(const CGHeroInstance * hero, EArmyFormation mode)=0;
|
||||
|
||||
virtual void save(const std::string &fname) = 0;
|
||||
virtual void sendMessage(const std::string &mess, const CGObjectInstance * currentObject = nullptr) = 0;
|
||||
@ -181,9 +182,9 @@ public:
|
||||
void endTurn() override;
|
||||
void swapGarrisonHero(const CGTownInstance *town) override;
|
||||
void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) override;
|
||||
void trade(const IMarket * market, EMarketMode mode, ui32 id1, ui32 id2, ui32 val1, const CGHeroInstance * hero = nullptr) override;
|
||||
void trade(const IMarket * market, EMarketMode mode, const std::vector<ui32> & id1, const std::vector<ui32> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr) override;
|
||||
void setFormation(const CGHeroInstance * hero, bool tight) override;
|
||||
void trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr) override;
|
||||
void trade(const IMarket * market, EMarketMode mode, const std::vector<TradeItemSell> & id1, const std::vector<TradeItemBuy> & id2, const std::vector<ui32> & val1, const CGHeroInstance * hero = nullptr) override;
|
||||
void setFormation(const CGHeroInstance * hero, EArmyFormation mode) override;
|
||||
void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero) override;
|
||||
void save(const std::string &fname) override;
|
||||
void sendMessage(const std::string &mess, const CGObjectInstance * currentObject = nullptr) override;
|
||||
|
@ -162,7 +162,7 @@ public:
|
||||
|
||||
void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> & spells) override {};
|
||||
bool removeObject(const CGObjectInstance * obj, const PlayerColor & initiator) override {return false;};
|
||||
void createObject(const int3 & visitablePosition, const PlayerColor & initiator, Obj type, int32_t subtype ) override {};
|
||||
void createObject(const int3 & visitablePosition, const PlayerColor & initiator, MapObjectID type, MapObjectSubID subtype) override {};
|
||||
void setOwner(const CGObjectInstance * obj, PlayerColor owner) override {};
|
||||
void changePrimSkill(const CGHeroInstance * hero, PrimarySkill which, si64 val, bool abs = false) override {};
|
||||
void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs = false) override {};
|
||||
@ -212,7 +212,8 @@ public:
|
||||
void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, ETileVisibility mode) override {}
|
||||
void changeFogOfWar(std::unordered_set<int3> & tiles, PlayerColor player, ETileVisibility mode) override {}
|
||||
|
||||
void setObjProperty(ObjectInstanceID objid, int prop, si64 val) override {}
|
||||
void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value) override {};
|
||||
void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) override {};
|
||||
|
||||
void showInfoDialog(InfoWindow * iw) override {};
|
||||
void showInfoDialog(const std::string & msg, PlayerColor player) override {};
|
||||
|
@ -350,15 +350,16 @@ void ApplyClientNetPackVisitor::visitGiveBonus(GiveBonus & pack)
|
||||
cl.invalidatePaths();
|
||||
switch(pack.who)
|
||||
{
|
||||
case GiveBonus::ETarget::HERO:
|
||||
case GiveBonus::ETarget::OBJECT:
|
||||
{
|
||||
const CGHeroInstance *h = gs.getHero(ObjectInstanceID(pack.id));
|
||||
callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, true);
|
||||
const CGHeroInstance *h = gs.getHero(pack.id.as<ObjectInstanceID>());
|
||||
if (h)
|
||||
callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, true);
|
||||
}
|
||||
break;
|
||||
case GiveBonus::ETarget::PLAYER:
|
||||
{
|
||||
callInterfaceIfPresent(cl, PlayerColor(pack.id), &IGameEventsReceiver::playerBonusChanged, pack.bonus, true);
|
||||
callInterfaceIfPresent(cl, pack.id.as<PlayerColor>(), &IGameEventsReceiver::playerBonusChanged, pack.bonus, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -433,16 +434,17 @@ void ApplyClientNetPackVisitor::visitRemoveBonus(RemoveBonus & pack)
|
||||
cl.invalidatePaths();
|
||||
switch(pack.who)
|
||||
{
|
||||
case GiveBonus::ETarget::HERO:
|
||||
case GiveBonus::ETarget::OBJECT:
|
||||
{
|
||||
const CGHeroInstance *h = gs.getHero(ObjectInstanceID(pack.whoID));
|
||||
callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, false);
|
||||
const CGHeroInstance *h = gs.getHero(pack.whoID.as<ObjectInstanceID>());
|
||||
if (h)
|
||||
callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, false);
|
||||
}
|
||||
break;
|
||||
case GiveBonus::ETarget::PLAYER:
|
||||
{
|
||||
//const PlayerState *p = gs.getPlayerState(pack.id);
|
||||
callInterfaceIfPresent(cl, PlayerColor(pack.whoID), &IGameEventsReceiver::playerBonusChanged, pack.bonus, false);
|
||||
callInterfaceIfPresent(cl, pack.whoID.as<PlayerColor>(), &IGameEventsReceiver::playerBonusChanged, pack.bonus, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -99,14 +99,15 @@ TExpType CAltarArtifacts::calcExpAltarForHero()
|
||||
|
||||
void CAltarArtifacts::makeDeal()
|
||||
{
|
||||
std::vector<ui32> positions;
|
||||
std::vector<TradeItemSell> positions;
|
||||
for(const auto art : arts->artifactsOnAltar)
|
||||
{
|
||||
positions.push_back(hero->getSlotByInstance(art));
|
||||
}
|
||||
std::sort(positions.begin(), positions.end(), std::greater<>());
|
||||
std::sort(positions.begin(), positions.end());
|
||||
std::reverse(positions.begin(), positions.end());
|
||||
|
||||
LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_EXP, positions, {}, {}, hero);
|
||||
LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_EXP, positions, std::vector<TradeItemBuy>(), std::vector<ui32>(), hero);
|
||||
arts->artifactsOnAltar.clear();
|
||||
|
||||
for(auto item : items[0])
|
||||
@ -374,14 +375,14 @@ void CAltarCreatures::makeDeal()
|
||||
unitsSlider->scrollTo(0);
|
||||
expForHero->setText(std::to_string(0));
|
||||
|
||||
std::vector<ui32> ids;
|
||||
std::vector<TradeItemSell> ids;
|
||||
std::vector<ui32> toSacrifice;
|
||||
|
||||
for(int i = 0; i < unitsOnAltar.size(); i++)
|
||||
{
|
||||
if(unitsOnAltar[i])
|
||||
{
|
||||
ids.push_back(i);
|
||||
ids.push_back(SlotID(i));
|
||||
toSacrifice.push_back(unitsOnAltar[i]);
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
|
||||
formations->resetCallback();
|
||||
//setting formations
|
||||
formations->setSelected(curHero->formation == EArmyFormation::TIGHT ? 1 : 0);
|
||||
formations->addCallback([=](int value){ LOCPLINT->cb->setFormation(curHero, value);});
|
||||
formations->addCallback([=](int value){ LOCPLINT->cb->setFormation(curHero, static_cast<EArmyFormation>(value));});
|
||||
|
||||
morale->set(curHero);
|
||||
luck->set(curHero);
|
||||
|
@ -503,14 +503,27 @@ void CMarketplaceWindow::makeDeal()
|
||||
|
||||
if(allowDeal)
|
||||
{
|
||||
if(slider)
|
||||
switch(mode)
|
||||
{
|
||||
LOCPLINT->cb->trade(market, mode, leftIdToSend, hRight->id, slider->getValue() * r1, hero);
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), GameResID(hRight->id), slider->getValue() * r1, hero);
|
||||
slider->scrollTo(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->cb->trade(market, mode, leftIdToSend, hRight->id, r2, hero);
|
||||
break;
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
LOCPLINT->cb->trade(market, mode, SlotID(leftIdToSend), GameResID(hRight->id), slider->getValue() * r1, hero);
|
||||
slider->scrollTo(0);
|
||||
break;
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), PlayerColor(hRight->id), slider->getValue() * r1, hero);
|
||||
slider->scrollTo(0);
|
||||
break;
|
||||
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), ArtifactID(hRight->id), r2, hero);
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
LOCPLINT->cb->trade(market, mode, ArtifactInstanceID(leftIdToSend), GameResID(hRight->id), r2, hero);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -988,7 +988,7 @@ void CTransformerWindow::makeDeal()
|
||||
for(auto & elem : items)
|
||||
{
|
||||
if(!elem->left)
|
||||
LOCPLINT->cb->trade(market, EMarketMode::CREATURE_UNDEAD, elem->id, 0, 0, hero);
|
||||
LOCPLINT->cb->trade(market, EMarketMode::CREATURE_UNDEAD, SlotID(elem->id), {}, {}, hero);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1163,13 +1163,13 @@ void CUniversityWindow::close()
|
||||
CStatusbarWindow::close();
|
||||
}
|
||||
|
||||
void CUniversityWindow::makeDeal(int skill)
|
||||
void CUniversityWindow::makeDeal(SecondarySkill skill)
|
||||
{
|
||||
LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_SKILL, 6, skill, 1, hero);
|
||||
LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_SKILL, GameResID(GameResID::GOLD), skill, 1, hero);
|
||||
}
|
||||
|
||||
|
||||
CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bool available)
|
||||
CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, SecondarySkill SKILL, bool available)
|
||||
: CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("UNIVERS2.PCX")),
|
||||
owner(owner_)
|
||||
{
|
||||
@ -1204,7 +1204,7 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
}
|
||||
|
||||
void CUnivConfirmWindow::makeDeal(int skill)
|
||||
void CUnivConfirmWindow::makeDeal(SecondarySkill skill)
|
||||
{
|
||||
owner->makeDeal(skill);
|
||||
close();
|
||||
|
@ -403,7 +403,7 @@ class CUniversityWindow : public CStatusbarWindow
|
||||
public:
|
||||
CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market, const std::function<void()> & onWindowClosed);
|
||||
|
||||
void makeDeal(int skill);
|
||||
void makeDeal(SecondarySkill skill);
|
||||
void close();
|
||||
};
|
||||
|
||||
@ -422,10 +422,10 @@ class CUnivConfirmWindow : public CStatusbarWindow
|
||||
std::shared_ptr<CAnimImage> costIcon;
|
||||
std::shared_ptr<CLabel> cost;
|
||||
|
||||
void makeDeal(int skill);
|
||||
void makeDeal(SecondarySkill skill);
|
||||
|
||||
public:
|
||||
CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available);
|
||||
CUnivConfirmWindow(CUniversityWindow * PARENT, SecondarySkill SKILL, bool available);
|
||||
};
|
||||
|
||||
/// Garrison window where you can take creatures out of the hero to place it on the garrison
|
||||
|
@ -484,12 +484,14 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/networkPacks/EOpenWindowMode.h
|
||||
${MAIN_LIB_DIR}/networkPacks/NetPacksBase.h
|
||||
${MAIN_LIB_DIR}/networkPacks/NetPackVisitor.h
|
||||
${MAIN_LIB_DIR}/networkPacks/ObjProperty.h
|
||||
${MAIN_LIB_DIR}/networkPacks/PacksForClient.h
|
||||
${MAIN_LIB_DIR}/networkPacks/PacksForClientBattle.h
|
||||
${MAIN_LIB_DIR}/networkPacks/PacksForLobby.h
|
||||
${MAIN_LIB_DIR}/networkPacks/PacksForServer.h
|
||||
${MAIN_LIB_DIR}/networkPacks/SetStackEffect.h
|
||||
${MAIN_LIB_DIR}/networkPacks/StackLocation.h
|
||||
${MAIN_LIB_DIR}/networkPacks/TradeItem.h
|
||||
|
||||
${MAIN_LIB_DIR}/pathfinder/INodeStorage.h
|
||||
${MAIN_LIB_DIR}/pathfinder/CGPathNode.h
|
||||
|
@ -415,12 +415,9 @@ int CCreatureSet::stacksCount() const
|
||||
return static_cast<int>(stacks.size());
|
||||
}
|
||||
|
||||
void CCreatureSet::setFormation(bool tight)
|
||||
void CCreatureSet::setFormation(EArmyFormation mode)
|
||||
{
|
||||
if (tight)
|
||||
formation = EArmyFormation::TIGHT;
|
||||
else
|
||||
formation = EArmyFormation::LOOSE;
|
||||
formation = mode;
|
||||
}
|
||||
|
||||
void CCreatureSet::setStackCount(const SlotID & slot, TQuantity count)
|
||||
|
@ -203,12 +203,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum class EArmyFormation : uint8_t
|
||||
{
|
||||
LOOSE,
|
||||
TIGHT
|
||||
};
|
||||
|
||||
namespace NArmyFormation
|
||||
{
|
||||
static const std::vector<std::string> names{ "wide", "tight" };
|
||||
@ -235,7 +229,7 @@ public:
|
||||
void addToSlot(const SlotID & slot, const CreatureID & cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
|
||||
void addToSlot(const SlotID & slot, CStackInstance * stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
|
||||
void clearSlots() override;
|
||||
void setFormation(bool tight);
|
||||
void setFormation(EArmyFormation tight);
|
||||
CArmedInstance *castToArmyObj();
|
||||
|
||||
//basic operations
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "CGameInfoCallback.h" // for CGameInfoCallback
|
||||
#include "CRandomGenerator.h"
|
||||
#include "networkPacks/ObjProperty.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -73,14 +74,15 @@ public:
|
||||
class DLL_LINKAGE IGameEventCallback
|
||||
{
|
||||
public:
|
||||
virtual void setObjProperty(ObjectInstanceID objid, int prop, si64 val) = 0;
|
||||
virtual void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value = 0) = 0;
|
||||
virtual void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) = 0;
|
||||
|
||||
virtual void showInfoDialog(InfoWindow * iw) = 0;
|
||||
virtual void showInfoDialog(const std::string & msg, PlayerColor player) = 0;
|
||||
|
||||
virtual void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> &spells)=0;
|
||||
virtual bool removeObject(const CGObjectInstance * obj, const PlayerColor & initiator) = 0;
|
||||
virtual void createObject(const int3 & visitablePosition, const PlayerColor & initiator, Obj type, int32_t subtype = 0) = 0;
|
||||
virtual void createObject(const int3 & visitablePosition, const PlayerColor & initiator, MapObjectID type, MapObjectSubID subtype) = 0;
|
||||
virtual void setOwner(const CGObjectInstance * objid, PlayerColor owner)=0;
|
||||
virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill which, si64 val, bool abs=false)=0;
|
||||
virtual void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false)=0;
|
||||
|
@ -246,4 +246,10 @@ enum class ETileVisibility : int8_t // Fog of war change
|
||||
REVEALED
|
||||
};
|
||||
|
||||
enum class EArmyFormation : int8_t
|
||||
{
|
||||
LOOSE,
|
||||
TIGHT
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
/// This class represents field that may contain value of multiple different identifer types
|
||||
/// This class represents field that may contain value of multiple different identifier types
|
||||
template<typename... Types>
|
||||
class VariantIdentifier
|
||||
{
|
||||
|
@ -94,12 +94,12 @@ void CBank::setConfig(const BankConfig & config)
|
||||
setCreature (SlotID(stacksCount()), stack.type->getId(), stack.count);
|
||||
}
|
||||
|
||||
void CBank::setPropertyDer (ui8 what, ui32 val)
|
||||
void CBank::setPropertyDer (ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case ObjProperty::BANK_DAYCOUNTER: //daycounter
|
||||
daycounter+=val;
|
||||
daycounter+= identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::BANK_RESET:
|
||||
// FIXME: Object reset must be done by separate netpack from server
|
||||
@ -119,9 +119,9 @@ void CBank::newTurn(CRandomGenerator & rand) const
|
||||
if (resetDuration != 0)
|
||||
{
|
||||
if (daycounter >= resetDuration)
|
||||
cb->setObjProperty (id, ObjProperty::BANK_RESET, 0); //daycounter 0
|
||||
cb->setObjPropertyValue(id, ObjProperty::BANK_RESET); //daycounter 0
|
||||
else
|
||||
cb->setObjProperty (id, ObjProperty::BANK_DAYCOUNTER, 1); //daycounter++
|
||||
cb->setObjPropertyValue(id, ObjProperty::BANK_DAYCOUNTER, 1); //daycounter++
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,7 +210,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
case Obj::CRYPT:
|
||||
{
|
||||
GiveBonus gbonus;
|
||||
gbonus.id = hero->id.getNum();
|
||||
gbonus.id = hero->id;
|
||||
gbonus.bonus.duration = BonusDuration::ONE_BATTLE;
|
||||
gbonus.bonus.source = BonusSource::OBJECT_TYPE;
|
||||
gbonus.bonus.sid = BonusSourceID(ID);
|
||||
@ -240,7 +240,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
{
|
||||
GiveBonus gb;
|
||||
gb.bonus = Bonus(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, -2, BonusSourceID(id), VLC->generaltexth->arraytxt[70]);
|
||||
gb.id = hero->id.getNum();
|
||||
gb.id = hero->id;
|
||||
cb->giveHeroBonus(&gb);
|
||||
textID = 107;
|
||||
iw.components.emplace_back(ComponentType::LUCK, -2);
|
||||
@ -369,7 +369,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->giveCreatures(this, hero, ourArmy, false);
|
||||
}
|
||||
cb->setObjProperty(id, ObjProperty::BANK_CLEAR, 0); //bc = nullptr
|
||||
cb->setObjPropertyValue(id, ObjProperty::BANK_CLEAR); //bc = nullptr
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ class DLL_LINKAGE CBank : public CArmedInstance
|
||||
ui32 resetDuration;
|
||||
bool coastVisitable;
|
||||
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void doVisit(const CGHeroInstance * hero) const;
|
||||
|
||||
public:
|
||||
|
@ -266,31 +266,28 @@ void CGCreature::newTurn(CRandomGenerator & rand) const
|
||||
if (stacks.begin()->second->count < VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP) && cb->getDate(Date::DAY_OF_WEEK) == 1 && cb->getDate(Date::DAY) > 1)
|
||||
{
|
||||
ui32 power = static_cast<ui32>(temppower * (100 + VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT)) / 100);
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_COUNT, std::min<uint32_t>(power / 1000, VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP))); //set new amount
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_POWER, power); //increase temppower
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_COUNT, std::min<uint32_t>(power / 1000, VLC->settings()->getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP))); //set new amount
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_POWER, power); //increase temppower
|
||||
}
|
||||
}
|
||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_EXP, VLC->settings()->getInteger(EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE)); //for testing purpose
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_EXP, VLC->settings()->getInteger(EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE)); //for testing purpose
|
||||
}
|
||||
void CGCreature::setPropertyDer(ui8 what, ui32 val)
|
||||
void CGCreature::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case ObjProperty::MONSTER_COUNT:
|
||||
stacks[SlotID(0)]->count = val;
|
||||
stacks[SlotID(0)]->count = identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::MONSTER_POWER:
|
||||
temppower = val;
|
||||
temppower = identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::MONSTER_EXP:
|
||||
giveStackExp(val);
|
||||
break;
|
||||
case ObjProperty::MONSTER_RESTORE_TYPE:
|
||||
formation.basicType = val;
|
||||
giveStackExp(identifier.getNum());
|
||||
break;
|
||||
case ObjProperty::MONSTER_REFUSED_JOIN:
|
||||
refusedJoining = val;
|
||||
refusedJoining = identifier.getNum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -368,7 +365,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
||||
void CGCreature::fleeDecision(const CGHeroInstance *h, ui32 pursue) const
|
||||
{
|
||||
if(refusedJoining)
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_REFUSED_JOIN, false);
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_REFUSED_JOIN, false);
|
||||
|
||||
if(pursue)
|
||||
{
|
||||
@ -386,7 +383,7 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co
|
||||
{
|
||||
if(takenAction(h,false) == FLEE)
|
||||
{
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_REFUSED_JOIN, true);
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_REFUSED_JOIN, true);
|
||||
flee(h);
|
||||
}
|
||||
else //they fight
|
||||
@ -421,10 +418,6 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co
|
||||
void CGCreature::fight( const CGHeroInstance *h ) const
|
||||
{
|
||||
//split stacks
|
||||
//TODO: multiple creature types in a stack?
|
||||
int basicType = stacks.begin()->second->type->getId();
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_RESTORE_TYPE, basicType); //store info about creature stack
|
||||
|
||||
int stacksCount = getNumberOfStacks(h);
|
||||
//source: http://heroescommunity.com/viewthread.php3?TID=27539&PID=1266335#focus
|
||||
|
||||
@ -488,7 +481,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
{
|
||||
//merge stacks into one
|
||||
TSlots::const_iterator i;
|
||||
CCreature * cre = VLC->creh->objects[formation.basicType];
|
||||
const CCreature * cre = getCreature().toCreature();
|
||||
for(i = stacks.begin(); i != stacks.end(); i++)
|
||||
{
|
||||
if(cre->isMyUpgrade(i->second->type))
|
||||
@ -513,7 +506,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
cb->moveStack(StackLocation(this, i->first), StackLocation(this, slot), i->second->count);
|
||||
}
|
||||
|
||||
cb->setObjProperty(id, ObjProperty::MONSTER_POWER, stacks.begin()->second->count * 1000); //remember casualties
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_POWER, stacks.begin()->second->count * 1000); //remember casualties
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,17 +54,6 @@ public:
|
||||
bool containsUpgradedStack() const;
|
||||
int getNumberOfStacks(const CGHeroInstance *hero) const;
|
||||
|
||||
struct DLL_LINKAGE formationInfo // info about merging stacks after battle back into one
|
||||
{
|
||||
si32 basicType;
|
||||
ui8 upgrade; //random seed used to determine number of stacks and is there's upgraded stack
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & basicType;
|
||||
h & upgrade;
|
||||
}
|
||||
} formation;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this);
|
||||
@ -80,7 +69,7 @@ public:
|
||||
h & formation;
|
||||
}
|
||||
protected:
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
|
||||
private:
|
||||
|
@ -201,7 +201,7 @@ void CGDwelling::initObj(CRandomGenerator & rand)
|
||||
}
|
||||
}
|
||||
|
||||
void CGDwelling::setPropertyDer(ui8 what, ui32 val)
|
||||
void CGDwelling::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
@ -214,14 +214,14 @@ void CGDwelling::setPropertyDer(ui8 what, ui32 val)
|
||||
std::vector<ConstTransitivePtr<CGDwelling> >* dwellings = &cb->gameState()->players[tempOwner].dwellings;
|
||||
dwellings->erase (std::find(dwellings->begin(), dwellings->end(), this));
|
||||
}
|
||||
if (PlayerColor(val) != PlayerColor::NEUTRAL) //can new owner be neutral?
|
||||
cb->gameState()->players[PlayerColor(val)].dwellings.emplace_back(this);
|
||||
if (identifier.as<PlayerColor>().isValidPlayer())
|
||||
cb->gameState()->players[identifier.as<PlayerColor>()].dwellings.emplace_back(this);
|
||||
}
|
||||
break;
|
||||
case ObjProperty::AVAILABLE_CREATURE:
|
||||
creatures.resize(1);
|
||||
creatures[0].second.resize(1);
|
||||
creatures[0].second[0] = CreatureID(val);
|
||||
creatures[0].second[0] = identifier.as<CreatureID>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -300,7 +300,7 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const
|
||||
|
||||
if(ID == Obj::REFUGEE_CAMP) //if it's a refugee camp, we need to pick an available creature
|
||||
{
|
||||
cb->setObjProperty(id, ObjProperty::AVAILABLE_CREATURE, VLC->creh->pickRandomMonster(rand));
|
||||
cb->setObjPropertyID(id, ObjProperty::AVAILABLE_CREATURE, VLC->creh->pickRandomMonster(rand));
|
||||
}
|
||||
|
||||
bool change = false;
|
||||
|
@ -52,7 +52,7 @@ private:
|
||||
void initObj(CRandomGenerator & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void newTurn(CRandomGenerator & rand) const override;
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
|
||||
std::vector<Component> getPopupComponents(PlayerColor player) const override;
|
||||
|
@ -348,7 +348,7 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
|
||||
if (gender == EHeroGender::DEFAULT)
|
||||
gender = type->gender;
|
||||
|
||||
setFormation(false);
|
||||
setFormation(EArmyFormation::LOOSE);
|
||||
if (!stacksCount()) //standard army//initial army
|
||||
{
|
||||
initArmy(rand);
|
||||
@ -501,7 +501,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
SetMovePoints smp;
|
||||
smp.hid = id;
|
||||
|
||||
cb->setManaPoints (id, manaLimit());
|
||||
cb->setManaPoints (id, manaLimit());
|
||||
|
||||
ObjectInstanceID boatId;
|
||||
const auto boatPos = visitablePos();
|
||||
@ -520,7 +520,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
smp.val = movementPointsLimit(true);
|
||||
}
|
||||
cb->giveHero(id, h->tempOwner, boatId); //recreates def and adds hero to player
|
||||
cb->setObjProperty(id, ObjProperty::ID, Obj::HERO); //set ID to 34 AFTER hero gets correct flag color
|
||||
cb->setObjPropertyID(id, ObjProperty::ID, Obj(Obj::HERO)); //set ID to 34 AFTER hero gets correct flag color
|
||||
cb->setMovePoints (&smp);
|
||||
|
||||
h->showInfoDialog(102);
|
||||
@ -620,10 +620,10 @@ void CGHeroInstance::updateSkillBonus(const SecondarySkill & which, int val)
|
||||
addNewBonus(std::make_shared<Bonus>(*b));
|
||||
}
|
||||
|
||||
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
|
||||
void CGHeroInstance::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
if(what == ObjProperty::PRIMARY_STACK_COUNT)
|
||||
setStackCount(SlotID(0), val);
|
||||
setStackCount(SlotID(0), identifier.getNum());
|
||||
}
|
||||
|
||||
double CGHeroInstance::getFightingStrength() const
|
||||
|
@ -307,7 +307,7 @@ public:
|
||||
bool isCoastVisitable() const override;
|
||||
BattleField getBattlefield() const override;
|
||||
protected:
|
||||
void setPropertyDer(ui8 what, ui32 val) override;//synchr
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;//synchr
|
||||
///common part of hero instance and hero definition
|
||||
void serializeCommonOptions(JsonSerializeFormat & handler);
|
||||
|
||||
|
@ -91,7 +91,7 @@ void CGBlackMarket::newTurn(CRandomGenerator & rand) const
|
||||
return;
|
||||
|
||||
SetAvailableArtifacts saa;
|
||||
saa.id = id.getNum();
|
||||
saa.id = id;
|
||||
cb->pickAllowedArtsSet(saa.arts, rand);
|
||||
cb->sendAndApply(&saa);
|
||||
}
|
||||
|
@ -181,23 +181,20 @@ void CGObjectInstance::initObj(CRandomGenerator & rand)
|
||||
}
|
||||
}
|
||||
|
||||
void CGObjectInstance::setProperty( ui8 what, ui32 val )
|
||||
void CGObjectInstance::setProperty( ObjProperty what, ObjPropertyID identifier )
|
||||
{
|
||||
setPropertyDer(what, val); // call this before any actual changes (needed at least for dwellings)
|
||||
setPropertyDer(what, identifier); // call this before any actual changes (needed at least for dwellings)
|
||||
|
||||
switch(what)
|
||||
{
|
||||
case ObjProperty::OWNER:
|
||||
tempOwner = PlayerColor(val);
|
||||
tempOwner = identifier.as<PlayerColor>();
|
||||
break;
|
||||
case ObjProperty::BLOCKVIS:
|
||||
blockVisit = val;
|
||||
blockVisit = identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::ID:
|
||||
ID = Obj(val);
|
||||
break;
|
||||
case ObjProperty::SUBID:
|
||||
subID = val;
|
||||
ID = identifier.as<MapObjectID>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -207,7 +204,7 @@ TObjectTypeHandler CGObjectInstance::getObjectHandler() const
|
||||
return VLC->objtypeh->getHandlerFor(ID, subID);
|
||||
}
|
||||
|
||||
void CGObjectInstance::setPropertyDer( ui8 what, ui32 val )
|
||||
void CGObjectInstance::setPropertyDer( ObjProperty what, ObjPropertyID identifier )
|
||||
{}
|
||||
|
||||
int3 CGObjectInstance::getSightCenter() const
|
||||
@ -229,7 +226,7 @@ void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDura
|
||||
{
|
||||
GiveBonus gbonus;
|
||||
gbonus.bonus.type = BonusType::NONE;
|
||||
gbonus.id = heroID.getNum();
|
||||
gbonus.id = heroID;
|
||||
gbonus.bonus.duration = duration;
|
||||
gbonus.bonus.source = BonusSource::OBJECT_TYPE;
|
||||
gbonus.bonus.sid = BonusSourceID(ID);
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
void pickRandomObject(CRandomGenerator & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
|
||||
void setProperty(ui8 what, ui32 val) final;
|
||||
void setProperty(ObjProperty what, ObjPropertyID identifier) final;
|
||||
|
||||
virtual void afterAddToMap(CMap * map);
|
||||
virtual void afterRemoveFromMap(CMap * map);
|
||||
@ -154,7 +154,7 @@ public:
|
||||
|
||||
protected:
|
||||
/// virtual method that allows synchronously update object state on server and all clients
|
||||
virtual void setPropertyDer(ui8 what, ui32 val);
|
||||
virtual void setPropertyDer(ObjProperty what, ObjPropertyID identifier);
|
||||
|
||||
/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
|
||||
void setType(MapObjectID ID, MapObjectSubID subID);
|
||||
|
@ -120,12 +120,12 @@ COPWBonus::COPWBonus(const BuildingID & bid, BuildingSubID::EBuildingSubID subId
|
||||
indexOnTV = static_cast<si32>(town->bonusingBuildings.size());
|
||||
}
|
||||
|
||||
void COPWBonus::setProperty(ui8 what, ui32 val)
|
||||
void COPWBonus::setProperty(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case ObjProperty::VISITORS:
|
||||
visitors.insert(val);
|
||||
visitors.insert(identifier.as<ObjectInstanceID>());
|
||||
break;
|
||||
case ObjProperty::STRUCTURE_CLEAR_VISITORS:
|
||||
visitors.clear();
|
||||
@ -148,7 +148,7 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
|
||||
{
|
||||
GiveBonus gb;
|
||||
gb.bonus = Bonus(BonusDuration::ONE_WEEK, BonusType::MOVEMENT, BonusSource::OBJECT_TYPE, 600, BonusSourceID(Obj(Obj::STABLES)), BonusCustomSubtype::heroMovementLand, VLC->generaltexth->arraytxt[100]);
|
||||
gb.id = heroID.getNum();
|
||||
gb.id = heroID;
|
||||
cb->giveHeroBonus(&gb);
|
||||
|
||||
SetMovePoints mp;
|
||||
@ -187,10 +187,10 @@ CTownBonus::CTownBonus(const BuildingID & index, BuildingSubID::EBuildingSubID s
|
||||
indexOnTV = static_cast<si32>(town->bonusingBuildings.size());
|
||||
}
|
||||
|
||||
void CTownBonus::setProperty (ui8 what, ui32 val)
|
||||
void CTownBonus::setProperty(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
if(what == ObjProperty::VISITORS)
|
||||
visitors.insert(ObjectInstanceID(val));
|
||||
visitors.insert(identifier.as<ObjectInstanceID>());
|
||||
}
|
||||
|
||||
void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
|
||||
@ -272,7 +272,7 @@ void CTownBonus::applyBonuses(CGHeroInstance * h, const BonusList & bonuses) con
|
||||
bonus->duration = BonusDuration::ONE_DAY;
|
||||
}
|
||||
gb.bonus = * bonus;
|
||||
gb.id = h->id.getNum();
|
||||
gb.id = h->id;
|
||||
cb->giveHeroBonus(&gb);
|
||||
|
||||
if(bonus->duration == BonusDuration::PERMANENT)
|
||||
@ -318,21 +318,21 @@ void CTownRewardableBuilding::newTurn(CRandomGenerator & rand) const
|
||||
{
|
||||
if(configuration.resetParameters.rewards)
|
||||
{
|
||||
cb->setObjProperty(town->id, ObjProperty::REWARD_RANDOMIZE, indexOnTV);
|
||||
cb->setObjPropertyValue(town->id, ObjProperty::REWARD_RANDOMIZE, indexOnTV);
|
||||
}
|
||||
if(configuration.resetParameters.visitors)
|
||||
{
|
||||
cb->setObjProperty(town->id, ObjProperty::STRUCTURE_CLEAR_VISITORS, indexOnTV);
|
||||
cb->setObjPropertyValue(town->id, ObjProperty::STRUCTURE_CLEAR_VISITORS, indexOnTV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTownRewardableBuilding::setProperty(ui8 what, ui32 val)
|
||||
void CTownRewardableBuilding::setProperty(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case ObjProperty::VISITORS:
|
||||
visitors.insert(ObjectInstanceID(val));
|
||||
visitors.insert(identifier.as<ObjectInstanceID>());
|
||||
break;
|
||||
case ObjProperty::STRUCTURE_CLEAR_VISITORS:
|
||||
visitors.clear();
|
||||
@ -341,7 +341,7 @@ void CTownRewardableBuilding::setProperty(ui8 what, ui32 val)
|
||||
initObj(cb->gameState()->getRandomGenerator());
|
||||
break;
|
||||
case ObjProperty::REWARD_SELECT:
|
||||
selectedReward = val;
|
||||
selectedReward = identifier.getNum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +69,8 @@ protected:
|
||||
class DLL_LINKAGE COPWBonus : public CGTownBuilding
|
||||
{///used for OPW bonusing structures
|
||||
public:
|
||||
std::set<si32> visitors;
|
||||
void setProperty(ui8 what, ui32 val) override;
|
||||
std::set<ObjectInstanceID> visitors;
|
||||
void setProperty(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void onHeroVisit (const CGHeroInstance * h) const override;
|
||||
|
||||
COPWBonus(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * TOWN);
|
||||
@ -89,7 +89,7 @@ class DLL_LINKAGE CTownBonus : public CGTownBuilding
|
||||
///feel free to merge inheritance tree
|
||||
public:
|
||||
std::set<ObjectInstanceID> visitors;
|
||||
void setProperty(ui8 what, ui32 val) override;
|
||||
void setProperty(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void onHeroVisit (const CGHeroInstance * h) const override;
|
||||
|
||||
CTownBonus(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * TOWN);
|
||||
@ -117,7 +117,7 @@ class DLL_LINKAGE CTownRewardableBuilding : public CGTownBuilding, public Reward
|
||||
void grantReward(ui32 rewardID, const CGHeroInstance * hero) const;
|
||||
|
||||
public:
|
||||
void setProperty(ui8 what, ui32 val) override;
|
||||
void setProperty(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
|
||||
void newTurn(CRandomGenerator & rand) const override;
|
||||
|
@ -53,28 +53,28 @@ int CGTownInstance::getSightRadius() const //returns sight distance
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGTownInstance::setPropertyDer(ui8 what, ui32 val)
|
||||
void CGTownInstance::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
///this is freakin' overcomplicated solution
|
||||
switch (what)
|
||||
{
|
||||
case ObjProperty::STRUCTURE_ADD_VISITING_HERO:
|
||||
bonusingBuildings[val]->setProperty(ObjProperty::VISITORS, visitingHero->id.getNum());
|
||||
bonusingBuildings[identifier.getNum()]->setProperty(ObjProperty::VISITORS, visitingHero->id);
|
||||
break;
|
||||
case ObjProperty::STRUCTURE_CLEAR_VISITORS:
|
||||
bonusingBuildings[val]->setProperty(ObjProperty::STRUCTURE_CLEAR_VISITORS, 0);
|
||||
bonusingBuildings[identifier.getNum()]->setProperty(ObjProperty::STRUCTURE_CLEAR_VISITORS, NumericID(0));
|
||||
break;
|
||||
case ObjProperty::STRUCTURE_ADD_GARRISONED_HERO: //add garrisoned hero to visitors
|
||||
bonusingBuildings[val]->setProperty(ObjProperty::VISITORS, garrisonHero->id.getNum());
|
||||
bonusingBuildings[identifier.getNum()]->setProperty(ObjProperty::VISITORS, garrisonHero->id);
|
||||
break;
|
||||
case ObjProperty::BONUS_VALUE_FIRST:
|
||||
bonusValue.first = val;
|
||||
bonusValue.first = identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::BONUS_VALUE_SECOND:
|
||||
bonusValue.second = val;
|
||||
bonusValue.second = identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::REWARD_RANDOMIZE:
|
||||
bonusingBuildings[val]->setProperty(ObjProperty::REWARD_RANDOMIZE, 0);
|
||||
bonusingBuildings[identifier.getNum()]->setProperty(ObjProperty::REWARD_RANDOMIZE, NumericID(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -534,12 +534,12 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const
|
||||
resID = (resID==2)?1:resID;
|
||||
int resVal = rand.nextInt(1, 4);//with size 1..4
|
||||
cb->giveResource(tempOwner, static_cast<EGameResID>(resID), resVal);
|
||||
cb->setObjProperty (id, ObjProperty::BONUS_VALUE_FIRST, resID);
|
||||
cb->setObjProperty (id, ObjProperty::BONUS_VALUE_SECOND, resVal);
|
||||
cb->setObjPropertyValue(id, ObjProperty::BONUS_VALUE_FIRST, resID);
|
||||
cb->setObjPropertyValue(id, ObjProperty::BONUS_VALUE_SECOND, resVal);
|
||||
}
|
||||
|
||||
for(const auto * manaVortex : getBonusingBuildings(BuildingSubID::MANA_VORTEX))
|
||||
cb->setObjProperty(id, ObjProperty::STRUCTURE_CLEAR_VISITORS, manaVortex->indexOnTV); //reset visitors for Mana Vortex
|
||||
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_CLEAR_VISITORS, manaVortex->indexOnTV); //reset visitors for Mana Vortex
|
||||
|
||||
//get Mana Vortex or Stables bonuses
|
||||
//same code is in the CGameHandler::buildStructure method
|
||||
@ -1072,9 +1072,9 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
||||
void CGTownInstance::addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID ) const
|
||||
{
|
||||
if(visitingHero == h)
|
||||
cb->setObjProperty(id, ObjProperty::STRUCTURE_ADD_VISITING_HERO, structureInstanceID); //add to visitors
|
||||
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_VISITING_HERO, structureInstanceID); //add to visitors
|
||||
else if(garrisonHero == h)
|
||||
cb->setObjProperty(id, ObjProperty::STRUCTURE_ADD_GARRISONED_HERO, structureInstanceID); //then it must be garrisoned hero
|
||||
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_GARRISONED_HERO, structureInstanceID); //then it must be garrisoned hero
|
||||
else
|
||||
{
|
||||
//should never ever happen
|
||||
|
@ -211,7 +211,7 @@ public:
|
||||
return defendingHero && garrisonHero && defendingHero != garrisonHero;
|
||||
}
|
||||
protected:
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
|
||||
|
||||
|
@ -544,18 +544,18 @@ std::vector<Component> CGSeerHut::getPopupComponents(const CGHeroInstance * hero
|
||||
return result;
|
||||
}
|
||||
|
||||
void CGSeerHut::setPropertyDer(ui8 what, ui32 val)
|
||||
void CGSeerHut::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch(what)
|
||||
{
|
||||
case CGSeerHut::SEERHUT_VISITED:
|
||||
case ObjProperty::SEERHUT_VISITED:
|
||||
{
|
||||
quest->activeForPlayers.emplace(val);
|
||||
quest->activeForPlayers.emplace(identifier.as<PlayerColor>());
|
||||
break;
|
||||
}
|
||||
case CGSeerHut::SEERHUT_COMPLETE:
|
||||
case ObjProperty::SEERHUT_COMPLETE:
|
||||
{
|
||||
quest->isCompleted = val;
|
||||
quest->isCompleted = identifier.getNum();
|
||||
quest->activeForPlayers.clear();
|
||||
break;
|
||||
}
|
||||
@ -567,7 +567,7 @@ void CGSeerHut::newTurn(CRandomGenerator & rand) const
|
||||
CRewardableObject::newTurn(rand);
|
||||
if(quest->lastDay >= 0 && quest->lastDay <= cb->getDate() - 1) //time is up
|
||||
{
|
||||
cb->setObjProperty (id, CGSeerHut::SEERHUT_COMPLETE, true);
|
||||
cb->setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
if(firstVisit)
|
||||
{
|
||||
cb->setObjProperty(id, CGSeerHut::SEERHUT_VISITED, h->getOwner());
|
||||
cb->setObjPropertyID(id, ObjProperty::SEERHUT_VISITED, h->getOwner());
|
||||
|
||||
AddQuest aq;
|
||||
aq.quest = QuestInfo (quest, this, visitablePos());
|
||||
@ -665,7 +665,7 @@ void CGSeerHut::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer)
|
||||
if(answer)
|
||||
{
|
||||
quest->completeQuest(cb, hero);
|
||||
cb->setObjProperty(id, CGSeerHut::SEERHUT_COMPLETE, !quest->repeatedQuest); //mission complete
|
||||
cb->setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, !quest->repeatedQuest); //mission complete
|
||||
}
|
||||
}
|
||||
|
||||
@ -764,7 +764,7 @@ void CGQuestGuard::onHeroVisit(const CGHeroInstance * h) const
|
||||
if(!quest->isCompleted)
|
||||
CGSeerHut::onHeroVisit(h);
|
||||
else
|
||||
cb->setObjProperty(id, CGSeerHut::SEERHUT_COMPLETE, false);
|
||||
cb->setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, false);
|
||||
}
|
||||
|
||||
bool CGQuestGuard::passableFor(PlayerColor color) const
|
||||
@ -783,15 +783,14 @@ void CGKeys::reset()
|
||||
playerKeyMap.clear();
|
||||
}
|
||||
|
||||
void CGKeys::setPropertyDer (ui8 what, ui32 val) //101-108 - enable key for player 1-8
|
||||
void CGKeys::setPropertyDer (ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
if (what >= 101 && what <= (100 + PlayerColor::PLAYER_LIMIT_I))
|
||||
if (what == ObjProperty::KEYMASTER_VISITED)
|
||||
{
|
||||
PlayerColor player(what-101);
|
||||
playerKeyMap[player].insert(static_cast<ui8>(val));
|
||||
playerKeyMap[identifier.as<PlayerColor>()].insert(subID);
|
||||
}
|
||||
else
|
||||
logGlobal->error("Unexpected properties requested to set: what=%d, val=%d", static_cast<int>(what), val);
|
||||
logGlobal->error("Unexpected properties requested to set: what=%d, val=%d", static_cast<int>(what), identifier.getNum());
|
||||
}
|
||||
|
||||
bool CGKeys::wasMyColorVisited(const PlayerColor & player) const
|
||||
@ -819,7 +818,7 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
int txt_id;
|
||||
if (!wasMyColorVisited (h->getOwner()) )
|
||||
{
|
||||
cb->setObjProperty(id, h->tempOwner.getNum()+101, subID);
|
||||
cb->setObjPropertyID(id, ObjProperty::KEYMASTER_VISITED, h->tempOwner);
|
||||
txt_id=19;
|
||||
}
|
||||
else
|
||||
|
@ -144,10 +144,7 @@ public:
|
||||
h & seerName;
|
||||
}
|
||||
protected:
|
||||
static constexpr int SEERHUT_VISITED = 10;
|
||||
static constexpr int SEERHUT_COMPLETE = 11;
|
||||
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
};
|
||||
@ -186,7 +183,7 @@ public:
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
protected:
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGKeymasterTent : public CGKeys
|
||||
|
@ -169,7 +169,7 @@ void CRewardableObject::blockingDialogAnswered(const CGHeroInstance *hero, ui32
|
||||
|
||||
void CRewardableObject::markAsVisited(const CGHeroInstance * hero) const
|
||||
{
|
||||
cb->setObjProperty(id, ObjProperty::REWARD_CLEARED, true);
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, true);
|
||||
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD, id, hero->id);
|
||||
cb->sendAndApply(&cov);
|
||||
@ -177,7 +177,7 @@ void CRewardableObject::markAsVisited(const CGHeroInstance * hero) const
|
||||
|
||||
void CRewardableObject::grantReward(ui32 rewardID, const CGHeroInstance * hero) const
|
||||
{
|
||||
cb->setObjProperty(id, ObjProperty::REWARD_SELECT, rewardID);
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_SELECT, rewardID);
|
||||
grantRewardBeforeLevelup(cb, configuration.info.at(rewardID), hero);
|
||||
|
||||
// hero is not blocked by levelup dialog - grant remainer immediately
|
||||
@ -338,7 +338,7 @@ std::vector<Component> CRewardableObject::getPopupComponents(const CGHeroInstanc
|
||||
return getPopupComponentsImpl(hero->getOwner(), hero);
|
||||
}
|
||||
|
||||
void CRewardableObject::setPropertyDer(ui8 what, ui32 val)
|
||||
void CRewardableObject::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
@ -346,10 +346,10 @@ void CRewardableObject::setPropertyDer(ui8 what, ui32 val)
|
||||
initObj(cb->gameState()->getRandomGenerator());
|
||||
break;
|
||||
case ObjProperty::REWARD_SELECT:
|
||||
selectedReward = val;
|
||||
selectedReward = identifier.getNum();
|
||||
break;
|
||||
case ObjProperty::REWARD_CLEARED:
|
||||
onceVisitableObjectCleared = val;
|
||||
onceVisitableObjectCleared = identifier.getNum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -360,11 +360,11 @@ void CRewardableObject::newTurn(CRandomGenerator & rand) const
|
||||
{
|
||||
if (configuration.resetParameters.rewards)
|
||||
{
|
||||
cb->setObjProperty(id, ObjProperty::REWARD_RANDOMIZE, 0);
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_RANDOMIZE, 0);
|
||||
}
|
||||
if (configuration.resetParameters.visitors)
|
||||
{
|
||||
cb->setObjProperty(id, ObjProperty::REWARD_CLEARED, false);
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, false);
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_CLEAR, id);
|
||||
cb->sendAndApply(&cov);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
|
||||
void initObj(CRandomGenerator & rand) override;
|
||||
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
|
||||
CRewardableObject();
|
||||
|
||||
|
@ -49,7 +49,7 @@ void IObjectInterface::initObj(CRandomGenerator & rand)
|
||||
void IObjectInterface::pickRandomObject(CRandomGenerator & rand)
|
||||
{}
|
||||
|
||||
void IObjectInterface::setProperty( ui8 what, ui32 val )
|
||||
void IObjectInterface::setProperty(ObjProperty what, ObjPropertyID identifier)
|
||||
{}
|
||||
|
||||
bool IObjectInterface::wasVisited (PlayerColor player) const
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../networkPacks/EInfoWindowMode.h"
|
||||
#include "../networkPacks/ObjProperty.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -46,7 +47,7 @@ public:
|
||||
virtual void newTurn(CRandomGenerator & rand) const;
|
||||
virtual void initObj(CRandomGenerator & rand); //synchr
|
||||
virtual void pickRandomObject(CRandomGenerator & rand);
|
||||
virtual void setProperty(ui8 what, ui32 val);//synchr
|
||||
virtual void setProperty(ObjProperty what, ObjPropertyID identifier);//synchr
|
||||
|
||||
//Called when queries created DURING HERO VISIT are resolved
|
||||
//First parameter is always hero that visited object and triggered the query
|
||||
|
@ -44,10 +44,10 @@ static std::string visitedTxt(const bool visited)
|
||||
return VLC->generaltexth->allTexts[id];
|
||||
}
|
||||
|
||||
void CTeamVisited::setPropertyDer(ui8 what, ui32 val)
|
||||
void CTeamVisited::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
if(what == CTeamVisited::OBJPROP_VISITED)
|
||||
players.insert(PlayerColor(val));
|
||||
if(what == ObjProperty::VISITED)
|
||||
players.insert(identifier.as<PlayerColor>());
|
||||
}
|
||||
|
||||
bool CTeamVisited::wasVisited(PlayerColor player) const
|
||||
@ -1195,13 +1195,13 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
|
||||
cb->sendAndApply(&iw);
|
||||
|
||||
// increment general visited obelisks counter
|
||||
cb->setObjProperty(id, CGObelisk::OBJPROP_INC, team.getNum());
|
||||
cb->setObjPropertyID(id, ObjProperty::OBELISK_VISITED, team);
|
||||
cb->showObjectWindow(this, EOpenWindowMode::PUZZLE_MAP, h, false);
|
||||
|
||||
// mark that particular obelisk as visited for all players in the team
|
||||
for(const auto & color : ts->players)
|
||||
{
|
||||
cb->setObjProperty(id, CGObelisk::OBJPROP_VISITED, color.getNum());
|
||||
cb->setObjPropertyID(id, ObjProperty::VISITED, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1228,14 +1228,14 @@ std::string CGObelisk::getHoverText(PlayerColor player) const
|
||||
return getObjectName() + " " + visitedTxt(wasVisited(player));
|
||||
}
|
||||
|
||||
void CGObelisk::setPropertyDer( ui8 what, ui32 val )
|
||||
void CGObelisk::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch(what)
|
||||
{
|
||||
case CGObelisk::OBJPROP_INC:
|
||||
case ObjProperty::OBELISK_VISITED:
|
||||
{
|
||||
auto progress = ++visited[TeamID(val)];
|
||||
logGlobal->debug("Player %d: obelisk progress %d / %d", val, static_cast<int>(progress) , static_cast<int>(obeliskCount));
|
||||
auto progress = ++visited[identifier.as<TeamID>()];
|
||||
logGlobal->debug("Player %d: obelisk progress %d / %d", identifier.getNum(), static_cast<int>(progress) , static_cast<int>(obeliskCount));
|
||||
|
||||
if(progress > obeliskCount)
|
||||
{
|
||||
@ -1246,7 +1246,7 @@ void CGObelisk::setPropertyDer( ui8 what, ui32 val )
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CTeamVisited::setPropertyDer(what, val);
|
||||
CTeamVisited::setPropertyDer(what, identifier);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1263,7 +1263,7 @@ void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
|
||||
if(oldOwner.isValidPlayer()) //remove bonus from old owner
|
||||
{
|
||||
RemoveBonus rb(GiveBonus::ETarget::PLAYER);
|
||||
rb.whoID = oldOwner.getNum();
|
||||
rb.whoID = oldOwner;
|
||||
rb.source = BonusSource::OBJECT_INSTANCE;
|
||||
rb.id = BonusSourceID(id);
|
||||
cb->sendAndApply(&rb);
|
||||
@ -1285,7 +1285,7 @@ void CGLighthouse::giveBonusTo(const PlayerColor & player, bool onInit) const
|
||||
GiveBonus gb(GiveBonus::ETarget::PLAYER);
|
||||
gb.bonus.type = BonusType::MOVEMENT;
|
||||
gb.bonus.val = 500;
|
||||
gb.id = player.getNum();
|
||||
gb.id = player;
|
||||
gb.bonus.duration = BonusDuration::PERMANENT;
|
||||
gb.bonus.source = BonusSource::OBJECT_INSTANCE;
|
||||
gb.bonus.sid = BonusSourceID(id);
|
||||
|
@ -29,15 +29,13 @@ public:
|
||||
bool wasVisited (const CGHeroInstance * h) const override;
|
||||
bool wasVisited(PlayerColor player) const override;
|
||||
bool wasVisited(const TeamID & team) const;
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
h & players;
|
||||
}
|
||||
|
||||
static constexpr int OBJPROP_VISITED = 10;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGSignBottle : public CGObjectInstance //signs and ocean bottles
|
||||
@ -361,7 +359,6 @@ class DLL_LINKAGE CGDenOfthieves : public CGObjectInstance
|
||||
class DLL_LINKAGE CGObelisk : public CTeamVisited
|
||||
{
|
||||
public:
|
||||
static constexpr int OBJPROP_INC = 20;
|
||||
static ui8 obeliskCount; //how many obelisks are on map
|
||||
static std::map<TeamID, ui8> visited; //map: team_id => how many obelisks has been visited
|
||||
|
||||
@ -375,7 +372,7 @@ public:
|
||||
h & static_cast<CTeamVisited&>(*this);
|
||||
}
|
||||
protected:
|
||||
void setPropertyDer(ui8 what, ui32 val) override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGLighthouse : public CGObjectInstance
|
||||
|
@ -971,18 +971,15 @@ void GiveBonus::applyGs(CGameState *gs)
|
||||
CBonusSystemNode *cbsn = nullptr;
|
||||
switch(who)
|
||||
{
|
||||
case ETarget::HERO:
|
||||
cbsn = gs->getHero(ObjectInstanceID(id));
|
||||
case ETarget::OBJECT:
|
||||
cbsn = dynamic_cast<CBonusSystemNode*>(gs->getObjInstance(id.as<ObjectInstanceID>()));
|
||||
break;
|
||||
case ETarget::PLAYER:
|
||||
cbsn = gs->getPlayerState(PlayerColor(id));
|
||||
break;
|
||||
case ETarget::TOWN:
|
||||
cbsn = gs->getTown(ObjectInstanceID(id));
|
||||
cbsn = gs->getPlayerState(id.as<PlayerColor>());
|
||||
break;
|
||||
case ETarget::BATTLE:
|
||||
assert(Bonus::OneBattle(&bonus));
|
||||
cbsn = dynamic_cast<CBonusSystemNode*>(gs->getBattle(BattleID(id)));
|
||||
cbsn = dynamic_cast<CBonusSystemNode*>(gs->getBattle(id.as<BattleID>()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1114,11 +1111,20 @@ void PlayerReinitInterface::applyGs(CGameState *gs)
|
||||
|
||||
void RemoveBonus::applyGs(CGameState *gs)
|
||||
{
|
||||
CBonusSystemNode * node = nullptr;
|
||||
if (who == GiveBonus::ETarget::HERO)
|
||||
node = gs->getHero(ObjectInstanceID(whoID));
|
||||
else
|
||||
node = gs->getPlayerState(PlayerColor(whoID));
|
||||
CBonusSystemNode *node = nullptr;
|
||||
switch(who)
|
||||
{
|
||||
case GiveBonus::ETarget::OBJECT:
|
||||
node = dynamic_cast<CBonusSystemNode*>(gs->getObjInstance(whoID.as<ObjectInstanceID>()));
|
||||
break;
|
||||
case GiveBonus::ETarget::PLAYER:
|
||||
node = gs->getPlayerState(whoID.as<PlayerColor>());
|
||||
break;
|
||||
case GiveBonus::ETarget::BATTLE:
|
||||
assert(Bonus::OneBattle(&bonus));
|
||||
node = dynamic_cast<CBonusSystemNode*>(gs->getBattle(whoID.as<BattleID>()));
|
||||
break;
|
||||
}
|
||||
|
||||
BonusList &bonuses = node->getExportedBonusList();
|
||||
|
||||
@ -1483,7 +1489,7 @@ void NewObject::applyGs(CGameState *gs)
|
||||
const TerrainTile & t = gs->map->getTile(targetPos);
|
||||
terrainType = t.terType->getId();
|
||||
|
||||
auto handler = VLC->objtypeh->getHandlerFor(ID, subID);
|
||||
auto handler = VLC->objtypeh->getHandlerFor(ID, subID.getNum());
|
||||
|
||||
CGObjectInstance * o = handler->create();
|
||||
handler->configureObject(o, gs->getRandomGenerator());
|
||||
@ -1499,13 +1505,13 @@ void NewObject::applyGs(CGameState *gs)
|
||||
cre->character = 2;
|
||||
cre->gainedArtifact = ArtifactID::NONE;
|
||||
cre->identifier = -1;
|
||||
cre->addToSlot(SlotID(0), new CStackInstance(CreatureID(subID), -1)); //add placeholder stack
|
||||
cre->addToSlot(SlotID(0), new CStackInstance(subID.as<CreatureID>(), -1)); //add placeholder stack
|
||||
}
|
||||
|
||||
assert(!handler->getTemplates(terrainType).empty());
|
||||
if (handler->getTemplates().empty())
|
||||
{
|
||||
logGlobal->error("Attempt to create object (%d %d) with no templates!", ID, subID);
|
||||
logGlobal->error("Attempt to create object (%d %d) with no templates!", ID, subID.getNum());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2049,9 +2055,9 @@ void SetObjectProperty::applyGs(CGameState * gs) const
|
||||
if(state->towns.empty())
|
||||
state->daysWithoutCastle = 0;
|
||||
}
|
||||
if(PlayerColor(val).isValidPlayer())
|
||||
if(identifier.as<PlayerColor>().isValidPlayer())
|
||||
{
|
||||
PlayerState * p = gs->getPlayerState(PlayerColor(val));
|
||||
PlayerState * p = gs->getPlayerState(identifier.as<PlayerColor>());
|
||||
p->towns.emplace_back(t);
|
||||
|
||||
//reset counter before NewTurn to avoid no town message if game loaded at turn when one already captured
|
||||
@ -2062,12 +2068,12 @@ void SetObjectProperty::applyGs(CGameState * gs) const
|
||||
|
||||
CBonusSystemNode & nodeToMove = cai->whatShouldBeAttached();
|
||||
nodeToMove.detachFrom(cai->whereShouldBeAttached(gs));
|
||||
obj->setProperty(what,val);
|
||||
obj->setProperty(what, identifier);
|
||||
nodeToMove.attachTo(cai->whereShouldBeAttached(gs));
|
||||
}
|
||||
else //not an armed instance
|
||||
{
|
||||
obj->setProperty(what,val);
|
||||
obj->setProperty(what, identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
69
lib/networkPacks/ObjProperty.h
Normal file
69
lib/networkPacks/ObjProperty.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ObjProperty.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 "../constants/VariantIdentifier.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
|
||||
enum class ObjProperty : int8_t
|
||||
{
|
||||
INVALID,
|
||||
OWNER,
|
||||
BLOCKVIS,
|
||||
PRIMARY_STACK_COUNT,
|
||||
VISITORS,
|
||||
VISITED,
|
||||
ID,
|
||||
AVAILABLE_CREATURE,
|
||||
MONSTER_COUNT,
|
||||
MONSTER_POWER,
|
||||
MONSTER_EXP,
|
||||
MONSTER_RESTORE_TYPE,
|
||||
MONSTER_REFUSED_JOIN,
|
||||
|
||||
//town-specific
|
||||
STRUCTURE_ADD_VISITING_HERO,
|
||||
STRUCTURE_CLEAR_VISITORS,
|
||||
STRUCTURE_ADD_GARRISONED_HERO, //changing buildings state
|
||||
BONUS_VALUE_FIRST,
|
||||
BONUS_VALUE_SECOND, //used in Rampart for special building that generates resources (storing resource type and quantity)
|
||||
|
||||
SEERHUT_VISITED,
|
||||
SEERHUT_COMPLETE,
|
||||
KEYMASTER_VISITED,
|
||||
OBELISK_VISITED,
|
||||
|
||||
//creature-bank specific
|
||||
BANK_DAYCOUNTER,
|
||||
BANK_RESET,
|
||||
BANK_CLEAR,
|
||||
|
||||
//object with reward
|
||||
REWARD_RANDOMIZE,
|
||||
REWARD_SELECT,
|
||||
REWARD_CLEARED
|
||||
};
|
||||
|
||||
class NumericID : public Identifier<NumericID>
|
||||
{
|
||||
public:
|
||||
using Identifier<NumericID>::Identifier;
|
||||
|
||||
static si32 decode(const std::string & identifier)
|
||||
{
|
||||
return std::stoi(identifier);
|
||||
}
|
||||
static std::string encode(const si32 index)
|
||||
{
|
||||
return std::to_string(index);
|
||||
}
|
||||
};
|
||||
|
||||
using ObjPropertyID = VariantIdentifier<NumericID, MapObjectID, ObjectInstanceID, CreatureID, PlayerColor, TeamID>;
|
@ -15,6 +15,7 @@
|
||||
#include "EOpenWindowMode.h"
|
||||
#include "EntityChanges.h"
|
||||
#include "NetPacksBase.h"
|
||||
#include "ObjProperty.h"
|
||||
|
||||
#include "../CCreatureSet.h"
|
||||
#include "../MetaString.h"
|
||||
@ -366,17 +367,17 @@ struct DLL_LINKAGE SetAvailableHero : public CPackForClient
|
||||
|
||||
struct DLL_LINKAGE GiveBonus : public CPackForClient
|
||||
{
|
||||
enum class ETarget : ui8 { HERO, PLAYER, TOWN, BATTLE };
|
||||
enum class ETarget : int8_t { OBJECT, PLAYER, BATTLE };
|
||||
|
||||
explicit GiveBonus(ETarget Who = ETarget::HERO)
|
||||
explicit GiveBonus(ETarget Who = ETarget::OBJECT)
|
||||
:who(Who)
|
||||
{
|
||||
}
|
||||
|
||||
void applyGs(CGameState * gs);
|
||||
|
||||
ETarget who = ETarget::HERO; //who receives bonus
|
||||
si32 id = 0; //hero. town or player id - whoever receives it
|
||||
ETarget who = ETarget::OBJECT;
|
||||
VariantIdentifier<ObjectInstanceID, PlayerColor, BattleID> id;
|
||||
Bonus bonus;
|
||||
MetaString bdescr;
|
||||
|
||||
@ -388,7 +389,7 @@ struct DLL_LINKAGE GiveBonus : public CPackForClient
|
||||
h & id;
|
||||
h & bdescr;
|
||||
h & who;
|
||||
assert(id != -1);
|
||||
assert(id.getNum() != -1);
|
||||
}
|
||||
};
|
||||
|
||||
@ -461,7 +462,7 @@ struct DLL_LINKAGE PlayerReinitInterface : public CPackForClient
|
||||
|
||||
struct DLL_LINKAGE RemoveBonus : public CPackForClient
|
||||
{
|
||||
explicit RemoveBonus(GiveBonus::ETarget Who = GiveBonus::ETarget::HERO)
|
||||
explicit RemoveBonus(GiveBonus::ETarget Who = GiveBonus::ETarget::OBJECT)
|
||||
:who(Who)
|
||||
{
|
||||
}
|
||||
@ -469,7 +470,7 @@ struct DLL_LINKAGE RemoveBonus : public CPackForClient
|
||||
void applyGs(CGameState * gs);
|
||||
|
||||
GiveBonus::ETarget who; //who receives bonus
|
||||
ui32 whoID = 0; //hero, town or player id - whoever loses bonus
|
||||
VariantIdentifier<HeroTypeID, PlayerColor, BattleID, ObjectInstanceID> whoID;
|
||||
|
||||
//vars to identify bonus: its source
|
||||
BonusSource source;
|
||||
@ -574,7 +575,7 @@ struct DLL_LINKAGE UpdateCastleEvents : public CPackForClient
|
||||
struct DLL_LINKAGE ChangeFormation : public CPackForClient
|
||||
{
|
||||
ObjectInstanceID hid;
|
||||
ui8 formation = 0;
|
||||
EArmyFormation formation{};
|
||||
|
||||
void applyGs(CGameState * gs) const;
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
@ -781,9 +782,9 @@ struct DLL_LINKAGE NewObject : public CPackForClient
|
||||
void applyGs(CGameState * gs);
|
||||
|
||||
/// Object ID to create
|
||||
Obj ID;
|
||||
MapObjectID ID;
|
||||
/// Object secondary ID to create
|
||||
ui32 subID = 0;
|
||||
VariantIdentifier<MapObjectSubID, HeroTypeID, CreatureID, BoatId> subID;
|
||||
/// Position of visitable tile of created object
|
||||
int3 targetPos;
|
||||
/// Which player initiated creation of this object
|
||||
@ -806,7 +807,8 @@ struct DLL_LINKAGE SetAvailableArtifacts : public CPackForClient
|
||||
{
|
||||
void applyGs(CGameState * gs) const;
|
||||
|
||||
si32 id = 0; //two variants: id < 0: set artifact pool for Artifact Merchants in towns; id >= 0: set pool for adv. map Black Market (id is the id of Black Market instance then)
|
||||
//two variants: id < 0: set artifact pool for Artifact Merchants in towns; id >= 0: set pool for adv. map Black Market (id is the id of Black Market instance then)
|
||||
ObjectInstanceID id;
|
||||
std::vector<const CArtifact *> arts;
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
@ -1207,38 +1209,16 @@ struct DLL_LINKAGE InfoWindow : public CPackForClient //103 - displays simple i
|
||||
InfoWindow() = default;
|
||||
};
|
||||
|
||||
namespace ObjProperty
|
||||
{
|
||||
enum
|
||||
{
|
||||
OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6, AVAILABLE_CREATURE = 7, SUBID = 8,
|
||||
MONSTER_COUNT = 10, MONSTER_POWER = 11, MONSTER_EXP = 12, MONSTER_RESTORE_TYPE = 13, MONSTER_REFUSED_JOIN,
|
||||
|
||||
//town-specific
|
||||
STRUCTURE_ADD_VISITING_HERO, STRUCTURE_CLEAR_VISITORS, STRUCTURE_ADD_GARRISONED_HERO, //changing buildings state
|
||||
BONUS_VALUE_FIRST, BONUS_VALUE_SECOND, //used in Rampart for special building that generates resources (storing resource type and quantity)
|
||||
|
||||
//creature-bank specific
|
||||
BANK_DAYCOUNTER, BANK_RESET, BANK_CLEAR,
|
||||
|
||||
//object with reward
|
||||
REWARD_RANDOMIZE, REWARD_SELECT, REWARD_CLEARED
|
||||
};
|
||||
}
|
||||
|
||||
struct DLL_LINKAGE SetObjectProperty : public CPackForClient
|
||||
{
|
||||
void applyGs(CGameState * gs) const;
|
||||
ObjectInstanceID id;
|
||||
ui8 what = 0; // see ObjProperty enum
|
||||
ui32 val = 0;
|
||||
ObjProperty what{};
|
||||
|
||||
ObjPropertyID identifier;
|
||||
int32_t value = 0;
|
||||
|
||||
SetObjectProperty() = default;
|
||||
SetObjectProperty(const ObjectInstanceID & ID, ui8 What, ui32 Val)
|
||||
: id(ID)
|
||||
, what(What)
|
||||
, val(Val)
|
||||
{
|
||||
}
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
@ -1246,7 +1226,8 @@ struct DLL_LINKAGE SetObjectProperty : public CPackForClient
|
||||
{
|
||||
h & id;
|
||||
h & what;
|
||||
h & val;
|
||||
h & identifier;
|
||||
h & value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "ArtifactLocation.h"
|
||||
#include "NetPacksBase.h"
|
||||
#include "TradeItem.h"
|
||||
|
||||
#include "../int3.h"
|
||||
#include "../battle/BattleAction.h"
|
||||
@ -472,7 +473,8 @@ struct DLL_LINKAGE TradeOnMarketplace : public CPackForServer
|
||||
ObjectInstanceID heroId;
|
||||
|
||||
EMarketMode mode = EMarketMode::RESOURCE_RESOURCE;
|
||||
std::vector<ui32> r1, r2; //mode 0: r1 - sold resource, r2 - bought res (exception: when sacrificing art r1 is art id [todo: make r2 preferred slot?]
|
||||
std::vector<TradeItemSell> r1;
|
||||
std::vector<TradeItemBuy> r2; //mode 0: r1 - sold resource, r2 - bought res (exception: when sacrificing art r1 is art id [todo: make r2 preferred slot?]
|
||||
std::vector<ui32> val; //units of sold resource
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
@ -493,13 +495,13 @@ struct DLL_LINKAGE SetFormation : public CPackForServer
|
||||
{
|
||||
SetFormation() = default;
|
||||
;
|
||||
SetFormation(const ObjectInstanceID & HID, ui8 Formation)
|
||||
SetFormation(const ObjectInstanceID & HID, EArmyFormation Formation)
|
||||
: hid(HID)
|
||||
, formation(Formation)
|
||||
{
|
||||
}
|
||||
ObjectInstanceID hid;
|
||||
ui8 formation = 0;
|
||||
EArmyFormation formation{};
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
|
20
lib/networkPacks/TradeItem.h
Normal file
20
lib/networkPacks/TradeItem.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* TradeItem.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 "../constants/VariantIdentifier.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
using TradeItemSell = VariantIdentifier<GameResID, SlotID, ArtifactPosition, ArtifactInstanceID>;
|
||||
using TradeItemBuy = VariantIdentifier<GameResID, PlayerColor, ArtifactID, SecondarySkill>;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -150,9 +150,9 @@ void Rewardable::Interface::grantRewardAfterLevelup(IGameCallback * cb, const Re
|
||||
for(const Bonus & bonus : info.reward.bonuses)
|
||||
{
|
||||
GiveBonus gb;
|
||||
gb.who = GiveBonus::ETarget::HERO;
|
||||
gb.who = GiveBonus::ETarget::OBJECT;
|
||||
gb.bonus = bonus;
|
||||
gb.id = hero->id.getNum();
|
||||
gb.id = hero->id;
|
||||
cb->giveHeroBonus(&gb);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(SpellCastEnviron
|
||||
for(const Bonus & b : bonuses)
|
||||
{
|
||||
GiveBonus gb;
|
||||
gb.id = parameters.caster->getCasterUnitId();
|
||||
gb.id = ObjectInstanceID(parameters.caster->getCasterUnitId());
|
||||
gb.bonus = b;
|
||||
env->apply(&gb);
|
||||
}
|
||||
@ -323,7 +323,7 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
|
||||
}
|
||||
|
||||
GiveBonus gb;
|
||||
gb.id = parameters.caster->getCasterUnitId();
|
||||
gb.id = ObjectInstanceID(parameters.caster->getCasterUnitId());
|
||||
gb.bonus = Bonus(BonusDuration::ONE_DAY, BonusType::NONE, BonusSource::SPELL_EFFECT, 0, BonusSourceID(owner->id));
|
||||
env->apply(&gb);
|
||||
|
||||
|
@ -117,7 +117,7 @@ void Moat::apply(ServerCallback * server, const Mechanics * m, const EffectTarge
|
||||
for(auto & b : converted)
|
||||
{
|
||||
GiveBonus gb(GiveBonus::ETarget::BATTLE);
|
||||
gb.id = m->battle()->getBattle()->getBattleID().getNum();
|
||||
gb.id = m->battle()->getBattle()->getBattleID();
|
||||
gb.bonus = b;
|
||||
server->apply(&gb);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ bool ArmyWidget::commitChanges()
|
||||
}
|
||||
}
|
||||
|
||||
army.setFormation(ui->formationTight->isChecked());
|
||||
army.setFormation(ui->formationTight->isChecked() ? EArmyFormation::TIGHT : EArmyFormation::LOOSE );
|
||||
return isArmed;
|
||||
}
|
||||
|
||||
|
@ -886,7 +886,7 @@ void CGameHandler::onNewTurn()
|
||||
if (newMonth)
|
||||
{
|
||||
SetAvailableArtifacts saa;
|
||||
saa.id = -1;
|
||||
saa.id = ObjectInstanceID::NONE;
|
||||
pickAllowedArtsSet(saa.arts, getRandomGenerator());
|
||||
sendAndApply(&saa);
|
||||
}
|
||||
@ -1328,8 +1328,8 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
|
||||
void CGameHandler::setOwner(const CGObjectInstance * obj, const PlayerColor owner)
|
||||
{
|
||||
PlayerColor oldOwner = getOwner(obj->id);
|
||||
SetObjectProperty sop(obj->id, ObjProperty::OWNER, owner.getNum());
|
||||
sendAndApply(&sop);
|
||||
|
||||
setObjPropertyID(obj->id, ObjProperty::OWNER, owner);
|
||||
|
||||
std::set<PlayerColor> playerColors = {owner, oldOwner};
|
||||
checkVictoryLossConditions(playerColors);
|
||||
@ -2973,12 +2973,12 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, GameRe
|
||||
SetAvailableArtifacts saa;
|
||||
if(dynamic_cast<const CGTownInstance *>(m))
|
||||
{
|
||||
saa.id = -1;
|
||||
saa.id = ObjectInstanceID::NONE;
|
||||
saa.arts = CGTownInstance::merchantArtifacts;
|
||||
}
|
||||
else if(const CGBlackMarket *bm = dynamic_cast<const CGBlackMarket *>(m)) //black market
|
||||
{
|
||||
saa.id = bm->id.getNum();
|
||||
saa.id = bm->id;
|
||||
saa.arts = bm->artifacts;
|
||||
}
|
||||
else
|
||||
@ -3044,23 +3044,23 @@ bool CGameHandler::buySecSkill(const IMarket *m, const CGHeroInstance *h, Second
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2)
|
||||
bool CGameHandler::tradeResources(const IMarket *market, ui32 amountToSell, PlayerColor player, GameResID toSell, GameResID toBuy)
|
||||
{
|
||||
TResourceCap r1 = getPlayerState(player)->resources[id1];
|
||||
TResourceCap haveToSell = getPlayerState(player)->resources[toSell];
|
||||
|
||||
vstd::amin(val, r1); //can't trade more resources than have
|
||||
vstd::amin(amountToSell, haveToSell); //can't trade more resources than have
|
||||
|
||||
int b1, b2; //base quantities for trade
|
||||
market->getOffer(id1, id2, b1, b2, EMarketMode::RESOURCE_RESOURCE);
|
||||
int units = val / b1; //how many base quantities we trade
|
||||
market->getOffer(toSell, toBuy, b1, b2, EMarketMode::RESOURCE_RESOURCE);
|
||||
int amountToBoy = amountToSell / b1; //how many base quantities we trade
|
||||
|
||||
if (val%b1) //all offered units of resource should be used, if not -> somewhere in calculations must be an error
|
||||
if (amountToSell % b1 != 0) //all offered units of resource should be used, if not -> somewhere in calculations must be an error
|
||||
{
|
||||
COMPLAIN_RET("Invalid deal, not all offered units of resource were used.");
|
||||
}
|
||||
|
||||
giveResource(player, GameResID(id1), - b1 * units);
|
||||
giveResource(player, GameResID(id2), b2 * units);
|
||||
giveResource(player, toSell, -b1 * amountToBoy);
|
||||
giveResource(player, toBuy, b2 * amountToBoy);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3144,7 +3144,7 @@ bool CGameHandler::sendResources(ui32 val, PlayerColor player, GameResID r1, Pla
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::setFormation(ObjectInstanceID hid, ui8 formation)
|
||||
bool CGameHandler::setFormation(ObjectInstanceID hid, EArmyFormation formation)
|
||||
{
|
||||
const CGHeroInstance *h = getHero(hid);
|
||||
if (!h)
|
||||
@ -4047,8 +4047,8 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
|
||||
createObject(*tile, PlayerColor::NEUTRAL, Obj::MONSTER, creatureID);
|
||||
auto monsterId = getTopObj(*tile)->id;
|
||||
|
||||
setObjProperty(monsterId, ObjProperty::MONSTER_COUNT, count);
|
||||
setObjProperty(monsterId, ObjProperty::MONSTER_POWER, (si64)1000*count);
|
||||
setObjPropertyValue(monsterId, ObjProperty::MONSTER_COUNT, count);
|
||||
setObjPropertyValue(monsterId, ObjProperty::MONSTER_POWER, (si64)1000*count);
|
||||
}
|
||||
tiles.erase(tile); //not use it again
|
||||
}
|
||||
@ -4170,12 +4170,21 @@ bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, con
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::setObjProperty(ObjectInstanceID objid, int prop, si64 val)
|
||||
void CGameHandler::setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value)
|
||||
{
|
||||
SetObjectProperty sob;
|
||||
sob.id = objid;
|
||||
sob.what = prop;
|
||||
sob.val = static_cast<ui32>(val);
|
||||
sob.identifier = NumericID(value);
|
||||
sendAndApply(&sob);
|
||||
}
|
||||
|
||||
void CGameHandler::setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier)
|
||||
{
|
||||
SetObjectProperty sob;
|
||||
sob.id = objid;
|
||||
sob.what = prop;
|
||||
sob.identifier = identifier;
|
||||
sendAndApply(&sob);
|
||||
}
|
||||
|
||||
@ -4209,7 +4218,7 @@ scripting::Pool * CGameHandler::getGlobalContextPool() const
|
||||
//}
|
||||
#endif
|
||||
|
||||
void CGameHandler::createObject(const int3 & visitablePosition, const PlayerColor & initiator, Obj type, int32_t subtype)
|
||||
void CGameHandler::createObject(const int3 & visitablePosition, const PlayerColor & initiator, MapObjectID type, MapObjectSubID subtype)
|
||||
{
|
||||
NewObject no;
|
||||
no.ID = type;
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
//do sth
|
||||
void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> &spells) override;
|
||||
bool removeObject(const CGObjectInstance * obj, const PlayerColor & initiator) override;
|
||||
void createObject(const int3 & visitablePosition, const PlayerColor & initiator, Obj type, int32_t subtype ) override;
|
||||
void createObject(const int3 & visitablePosition, const PlayerColor & initiator, MapObjectID type, MapObjectSubID subtype) override;
|
||||
void setOwner(const CGObjectInstance * obj, PlayerColor owner) override;
|
||||
void changePrimSkill(const CGHeroInstance * hero, PrimarySkill which, si64 val, bool abs=false) override;
|
||||
void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) override;
|
||||
@ -156,7 +156,8 @@ public:
|
||||
/// Returns hero that is currently visiting this object, or nullptr if no visit is active
|
||||
const CGHeroInstance * getVisitingHero(const CGObjectInstance *obj);
|
||||
bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) override;
|
||||
void setObjProperty(ObjectInstanceID objid, int prop, si64 val) override;
|
||||
void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value) override;
|
||||
void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) override;
|
||||
void showInfoDialog(InfoWindow * iw) override;
|
||||
void showInfoDialog(const std::string & msg, PlayerColor player) override;
|
||||
|
||||
@ -182,8 +183,8 @@ public:
|
||||
|
||||
bool queryReply( QueryID qid, std::optional<int32_t> reply, PlayerColor player );
|
||||
bool buildBoat( ObjectInstanceID objid, PlayerColor player );
|
||||
bool setFormation( ObjectInstanceID hid, ui8 formation );
|
||||
bool tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2);
|
||||
bool setFormation( ObjectInstanceID hid, EArmyFormation formation );
|
||||
bool tradeResources(const IMarket *market, ui32 amountToSell, PlayerColor player, GameResID toSell, GameResID toBuy);
|
||||
bool sacrificeCreatures(const IMarket * market, const CGHeroInstance * hero, const std::vector<SlotID> & slot, const std::vector<ui32> & count);
|
||||
bool sendResources(ui32 val, PlayerColor player, GameResID r1, PlayerColor r2);
|
||||
bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, GameResID resourceID);
|
||||
|
@ -221,42 +221,49 @@ void ApplyGhNetPackVisitor::visitTradeOnMarketplace(TradeOnMarketplace & pack)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.tradeResources(market, pack.val[i], pack.player, pack.r1[i], pack.r2[i]);
|
||||
result &= gh.tradeResources(market, pack.val[i], pack.player, pack.r1[i].as<GameResID>(), pack.r2[i].as<GameResID>());
|
||||
break;
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.sendResources(pack.val[i], pack.player, GameResID(pack.r1[i]), PlayerColor(pack.r2[i]));
|
||||
result &= gh.sendResources(pack.val[i], pack.player, pack.r1[i].as<GameResID>(), pack.r2[i].as<PlayerColor>());
|
||||
break;
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.sellCreatures(pack.val[i], market, hero, SlotID(pack.r1[i]), GameResID(pack.r2[i]));
|
||||
result &= gh.sellCreatures(pack.val[i], market, hero, pack.r1[i].as<SlotID>(), pack.r2[i].as<GameResID>());
|
||||
break;
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.buyArtifact(market, hero, GameResID(pack.r1[i]), ArtifactID(pack.r2[i]));
|
||||
result &= gh.buyArtifact(market, hero, pack.r1[i].as<GameResID>(), pack.r2[i].as<ArtifactID>());
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.sellArtifact(market, hero, ArtifactInstanceID(pack.r1[i]), GameResID(pack.r2[i]));
|
||||
result &= gh.sellArtifact(market, hero, pack.r1[i].as<ArtifactInstanceID>(), pack.r2[i].as<GameResID>());
|
||||
break;
|
||||
case EMarketMode::CREATURE_UNDEAD:
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.transformInUndead(market, hero, SlotID(pack.r1[i]));
|
||||
result &= gh.transformInUndead(market, hero, pack.r1[i].as<SlotID>());
|
||||
break;
|
||||
case EMarketMode::RESOURCE_SKILL:
|
||||
for(int i = 0; i < pack.r2.size(); ++i)
|
||||
result &= gh.buySecSkill(market, hero, SecondarySkill(pack.r2[i]));
|
||||
result &= gh.buySecSkill(market, hero, pack.r2[i].as<SecondarySkill>());
|
||||
break;
|
||||
case EMarketMode::CREATURE_EXP:
|
||||
{
|
||||
std::vector<SlotID> slotIDs(pack.r1.begin(), pack.r1.end());
|
||||
std::vector<SlotID> slotIDs;
|
||||
std::vector<ui32> count(pack.val.begin(), pack.val.end());
|
||||
|
||||
for(auto const & slot : pack.r1)
|
||||
slotIDs.push_back(slot.as<SlotID>());
|
||||
|
||||
result = gh.sacrificeCreatures(market, hero, slotIDs, count);
|
||||
return;
|
||||
}
|
||||
case EMarketMode::ARTIFACT_EXP:
|
||||
{
|
||||
std::vector<ArtifactPosition> positions(pack.r1.begin(), pack.r1.end());
|
||||
std::vector<ArtifactPosition> positions;
|
||||
for(auto const & slot : pack.r1)
|
||||
positions.push_back(slot.as<ArtifactPosition>());
|
||||
|
||||
result = gh.sacrificeArtifact(market, hero, positions);
|
||||
return;
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ void BattleProcessor::startBattlePrimary(const CArmedInstance *army1, const CArm
|
||||
{
|
||||
for(auto bonus : attackerInfo->battleBonuses)
|
||||
{
|
||||
GiveBonus giveBonus(GiveBonus::ETarget::HERO);
|
||||
giveBonus.id = hero1->id.getNum();
|
||||
GiveBonus giveBonus(GiveBonus::ETarget::OBJECT);
|
||||
giveBonus.id = hero1->id;
|
||||
giveBonus.bonus = bonus;
|
||||
gameHandler->sendAndApply(&giveBonus);
|
||||
}
|
||||
|
@ -139,8 +139,8 @@ void PlayerMessageProcessor::cheatGiveSpells(PlayerColor player, const CGHeroIns
|
||||
gameHandler->giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
|
||||
|
||||
///Give all spells with bonus (to allow banned spells)
|
||||
GiveBonus giveBonus(GiveBonus::ETarget::HERO);
|
||||
giveBonus.id = hero->id.getNum();
|
||||
GiveBonus giveBonus(GiveBonus::ETarget::OBJECT);
|
||||
giveBonus.id = hero->id;
|
||||
giveBonus.bonus = Bonus(BonusDuration::PERMANENT, BonusType::SPELLS_OF_LEVEL, BonusSource::OTHER, 0, BonusSourceID());
|
||||
//start with level 0 to skip abilities
|
||||
for (int level = 1; level <= GameConstants::SPELL_LEVELS; level++)
|
||||
@ -300,11 +300,11 @@ void PlayerMessageProcessor::cheatMovement(PlayerColor player, const CGHeroInsta
|
||||
|
||||
gameHandler->sendAndApply(&smp);
|
||||
|
||||
GiveBonus gb(GiveBonus::ETarget::HERO);
|
||||
GiveBonus gb(GiveBonus::ETarget::OBJECT);
|
||||
gb.bonus.type = BonusType::FREE_SHIP_BOARDING;
|
||||
gb.bonus.duration = BonusDuration::ONE_DAY;
|
||||
gb.bonus.source = BonusSource::OTHER;
|
||||
gb.id = hero->id.getNum();
|
||||
gb.id = hero->id;
|
||||
gameHandler->giveHeroBonus(&gb);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user