mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Some work on artifact assembly.
This commit is contained in:
parent
a6aa36c5a9
commit
ab75f4b1f8
@ -433,6 +433,24 @@ bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGH
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles or disassembles a combination artifact.
|
||||
* @param hero Hero holding the artifact(s).
|
||||
* @param artifactSlot The worn slot ID of the combination- or constituent artifact.
|
||||
* @param assemble True for assembly operation, false for disassembly.
|
||||
* @param assembleTo If assemble is true, this represents the artifact ID of the combination
|
||||
* artifact to assemble to. Otherwise it's not used.
|
||||
*/
|
||||
bool CCallback::assembleArtifacts (const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo)
|
||||
{
|
||||
if (player != hero->tempOwner)
|
||||
return false;
|
||||
|
||||
AssembleArtifacts aa(hero->id, artifactSlot, assemble, assembleTo);
|
||||
sendRequest(&aa);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
|
||||
{
|
||||
CGTownInstance * t = const_cast<CGTownInstance *>(town);
|
||||
|
@ -89,6 +89,7 @@ public:
|
||||
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type)
|
||||
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
||||
virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
|
||||
virtual bool assembleArtifacts(const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo)=0;
|
||||
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
|
||||
virtual void endTurn()=0;
|
||||
virtual void buyArtifact(const CGHeroInstance *hero, int aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith)
|
||||
@ -207,7 +208,7 @@ public:
|
||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
||||
bool dismissHero(const CGHeroInstance * hero);
|
||||
bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
|
||||
bool setArtifact(const CGHeroInstance * hero, ui16 pos, int artID);
|
||||
bool assembleArtifacts(const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo);
|
||||
bool buildBuilding(const CGTownInstance *town, si32 buildingID);
|
||||
void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount);
|
||||
bool dismissCreature(const CArmedInstance *obj, int stackPos);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "../lib/map.h"
|
||||
#include "../mapHandler.h"
|
||||
#include "../timeHandler.h"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -3689,8 +3690,23 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
|
||||
void CArtPlace::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(!locked() && text.size()) //if there is no description or it's a lock, do nothing ;]
|
||||
if(ourArt && !locked() && text.size()) { //if there is no description or it's a lock, do nothing ;]
|
||||
LRClickableAreaWTextComp::clickRight(down, previousState);
|
||||
|
||||
/*if (ourArt->constituentOf != NULL) {
|
||||
BOOST_FOREACH(ui32 combination, *ourArt->constituentOf) {
|
||||
if (ourArt->canBeAssembledTo(ourOwner->curHero->artifWorn, combination)) {
|
||||
LOCPLINT->cb->assembleArtifacts(ourOwner->curHero, slotID, true, combination);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ourArt->constituents != NULL) {
|
||||
LOCPLINT->cb->assembleArtifacts(ourOwner->curHero, slotID, false, 0);
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,6 +100,29 @@ bool CArtifact::fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slotID) cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CArtifact::canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 artifactID) const
|
||||
{
|
||||
if (constituentOf == NULL || !vstd::contains(*constituentOf, artifactID))
|
||||
return false;
|
||||
|
||||
const CArtifact &artifact = VLC->arth->artifacts[artifactID];
|
||||
assert(artifact.constituents);
|
||||
|
||||
BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
|
||||
bool found = false;
|
||||
for (std::map<ui16, ui32>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it) {
|
||||
if (it->second == constituentID) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CArtHandler::CArtHandler()
|
||||
{
|
||||
VLC->arth = this;
|
||||
@ -108,6 +131,15 @@ CArtHandler::CArtHandler()
|
||||
for (ui32 i = 3; i <= 6; i++)
|
||||
bigArtifacts.insert(i);
|
||||
}
|
||||
|
||||
CArtHandler::~CArtHandler()
|
||||
{
|
||||
for (std::vector<CArtifact>::iterator it = artifacts.begin(); it != artifacts.end(); ++it) {
|
||||
delete it->constituents;
|
||||
delete it->constituentOf;
|
||||
}
|
||||
}
|
||||
|
||||
void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
{
|
||||
std::vector<ui16> slots;
|
||||
@ -145,6 +177,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
desc = desc.substr(1,desc.size()-2);
|
||||
|
||||
// Fill in information about combined artifacts. Should perhaps be moved to a config file?
|
||||
nart.constituentOf = NULL;
|
||||
switch (nart.id) {
|
||||
case 129: // Angelic Alliance
|
||||
nart.constituents = new std::vector<ui32>();
|
||||
@ -219,6 +252,17 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
sortArts();
|
||||
if(!onlyTxt)
|
||||
addBonuses();
|
||||
|
||||
// Populate reverse mappings of combinational artifacts.
|
||||
BOOST_FOREACH(CArtifact artifact, artifacts) {
|
||||
if (artifact.constituents != NULL) {
|
||||
BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
|
||||
if (artifacts[constituentID].constituentOf == NULL)
|
||||
artifacts[constituentID].constituentOf = new std::vector<ui32>();
|
||||
artifacts[constituentID].constituentOf->push_back(artifact.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CArtHandler::convertMachineID(int id, bool creToArt )
|
||||
@ -507,6 +551,7 @@ void CArtHandler::addBonuses()
|
||||
giveArtBonus(134, HeroBonus::LEVEL_SPELL_IMMUNITY, 4);
|
||||
|
||||
//Titan's Thunder
|
||||
// should also add a permanent spell book, somehow.
|
||||
ART_ATTACK_AND_DEFENSE(135, +9);
|
||||
ART_POWER_AND_KNOWLEDGE(135, +8);
|
||||
giveArtBonus(135, HeroBonus::SPELL, 3, 57);
|
||||
@ -612,7 +657,6 @@ void CArtHandler::unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,17 +27,19 @@ public:
|
||||
const std::string &Description() const; //getter
|
||||
bool isBig () const;
|
||||
bool fitsAt (const std::map<ui16, ui32> &artifWorn, ui16 slot) const;
|
||||
bool canBeAssembledTo (const std::map<ui16, ui32> &artifWorn, ui32 artifactID) const;
|
||||
|
||||
ui32 price;
|
||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
||||
std::vector<ui32> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
|
||||
std::vector<ui32> * constituentOf; // Reverse map of constituents.
|
||||
EartClass aClass;
|
||||
ui32 id;
|
||||
std::list<HeroBonus> bonuses; //bonuses given by artifact
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & name & description & price & possibleSlots & constituents & aClass & id & bonuses;
|
||||
h & name & description & price & possibleSlots & constituents & constituentOf & aClass & id & bonuses;
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,6 +60,7 @@ public:
|
||||
void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID);
|
||||
static int convertMachineID(int id, bool creToArt);
|
||||
CArtHandler();
|
||||
~CArtHandler();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -1284,6 +1284,23 @@ struct ExchangeArtifacts : public CPackForServer
|
||||
}
|
||||
};
|
||||
|
||||
struct AssembleArtifacts : public CPackForServer
|
||||
{
|
||||
AssembleArtifacts(){};
|
||||
AssembleArtifacts(si32 _heroID, ui16 _artifactSlot, bool _assemble, ui32 _assembleTo)
|
||||
: heroID(_heroID), artifactSlot(_artifactSlot), assemble(_assemble), assembleTo(_assembleTo){};
|
||||
si32 heroID;
|
||||
ui16 artifactSlot;
|
||||
bool assemble; // True to assemble artifact, false to disassemble.
|
||||
ui32 assembleTo; // Artifact to assemble into.
|
||||
|
||||
bool applyGh(CGameHandler *gh);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & heroID & artifactSlot & assemble & assembleTo;
|
||||
}
|
||||
};
|
||||
|
||||
struct BuyArtifact : public CPackForServer
|
||||
{
|
||||
BuyArtifact(){};
|
||||
|
@ -143,6 +143,7 @@ void registerTypes3(Serializer &s)
|
||||
s.template registerType<UpgradeCreature>();
|
||||
s.template registerType<GarrisonHeroSwap>();
|
||||
s.template registerType<ExchangeArtifacts>();
|
||||
s.template registerType<AssembleArtifacts>();
|
||||
s.template registerType<BuyArtifact>();
|
||||
s.template registerType<TradeOnMarketplace>();
|
||||
s.template registerType<SetFormation>();
|
||||
|
@ -2625,6 +2625,85 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles or disassembles a combination artifact.
|
||||
* @param heroID ID of hero holding the artifact(s).
|
||||
* @param artifactSlot The worn slot ID of the combination- or constituent artifact.
|
||||
* @param assemble True for assembly operation, false for disassembly.
|
||||
* @param assembleTo If assemble is true, this represents the artifact ID of the combination
|
||||
* artifact to assemble to. Otherwise it's not used.
|
||||
*/
|
||||
bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo)
|
||||
{
|
||||
if (artifactSlot < 0 || artifactSlot > 18) {
|
||||
complain("Illegal artifact slot.");
|
||||
return false;
|
||||
}
|
||||
|
||||
CGHeroInstance *hero = gs->getHero(heroID);
|
||||
const CArtifact *destArtifact = hero->getArt(artifactSlot);
|
||||
|
||||
SetHeroArtifacts sha;
|
||||
sha.hid = heroID;
|
||||
sha.artifacts = hero->artifacts;
|
||||
sha.artifWorn = hero->artifWorn;
|
||||
|
||||
if (assemble) {
|
||||
if (VLC->arth->artifacts.size() >= assembleTo) {
|
||||
complain("Illegal artifact to assemble to.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!destArtifact->canBeAssembledTo(hero->artifWorn, assembleTo)) {
|
||||
complain("Artifact cannot be assembled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const CArtifact &artifact = VLC->arth->artifacts[assembleTo];
|
||||
|
||||
if (artifact.constituents == NULL) {
|
||||
complain("Not a combinational artifact.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
|
||||
BOOST_FOREACH(ui32 constituentID, *artifact.constituents) {
|
||||
bool found = false;
|
||||
for (std::map<ui16, ui32>::iterator it = sha.artifWorn.begin(); it != sha.artifWorn.end(); ++it) {
|
||||
if (it->second == constituentID) {
|
||||
if (!destConsumed && vstd::contains(artifact.possibleSlots, it->first)) {
|
||||
it->second = assembleTo;
|
||||
destConsumed = true;
|
||||
} else {
|
||||
it->second = 145;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
complain("Constituent missing.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BOOST_FOREACH(ui32 constituentID, *destArtifact->constituents) {
|
||||
const CArtifact &constituent = VLC->arth->artifacts[constituentID];
|
||||
|
||||
BOOST_REVERSE_FOREACH(ui16 slotID, constituent.possibleSlots) {
|
||||
if (sha.artifWorn.find(slotID) != sha.artifWorn.end()) {
|
||||
if (sha.artifWorn[slotID] == 145 || slotID == artifactSlot)
|
||||
sha.artifWorn[slotID] = constituentID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&sha);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(hid);
|
||||
|
@ -163,6 +163,7 @@ public:
|
||||
bool buildBoat( ui32 objid );
|
||||
bool setFormation( si32 hid, ui8 formation );
|
||||
bool tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 );
|
||||
bool assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo);
|
||||
bool buyArtifact( ui32 hid, si32 aid );
|
||||
bool swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot);
|
||||
bool garrisonSwap(si32 tid);
|
||||
|
@ -98,6 +98,12 @@ bool ExchangeArtifacts::applyGh( CGameHandler *gh )
|
||||
return gh->swapArtifacts(hid1,hid2,slot1,slot2);
|
||||
}
|
||||
|
||||
bool AssembleArtifacts::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(heroID);
|
||||
return gh->assembleArtifacts(heroID, artifactSlot, assemble, assembleTo);
|
||||
}
|
||||
|
||||
bool BuyArtifact::applyGh( CGameHandler *gh )
|
||||
{
|
||||
ERROR_IF_NOT_OWNS(hid);
|
||||
|
Loading…
Reference in New Issue
Block a user