1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Practically finished combined artifacts changes, many other fixes.

This commit is contained in:
Michał W. Urbańczyk 2011-01-28 02:11:58 +00:00
parent 092ab5a77f
commit a75a37008f
17 changed files with 419 additions and 315 deletions

View File

@ -72,7 +72,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
OBJ_CONSTRUCTION_CAPTURING_ALL;
garr = NULL;
curHero = hero;
player = hero->tempOwner;
player = LOCPLINT->playerID;//hero->tempOwner;
background = new CPicture("HeroScr4.BMP");
background->colorizeAndConvert(player);
@ -162,7 +162,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
}
assert(hero == curHero);
assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes
//assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes
specArea->text = CGI->generaltexth->hTxts[hero->subID].longBonus;

View File

@ -428,6 +428,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
{
playerint[255] = CAIHandler::getNewAI(cb,conf.cc.defaultAI);
playerint[255]->init(new CCallback(gs,255,this));
battleints[255] = playerint[255];
}
serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);

View File

@ -2630,7 +2630,7 @@ void CTradeWindow::CTradeableItem::showAll(SDL_Surface * to)
void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
{
CTradeWindow *mw = static_cast<CTradeWindow *>(parent);
CTradeWindow *mw = dynamic_cast<CTradeWindow *>(parent);
assert(mw);
if(down)
{
@ -2638,23 +2638,21 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
if(type == ARTIFACT_PLACEHOLDER)
{
CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art;
if(movedArt)
if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art)
{
aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this, movedArt);
}
else if(const CArtifactInstance *art = getArtInstance())
{
movedArt = art;
aw->arts->commonInfo->src.AOH = aw->arts;
aw->arts->commonInfo->src.art = movedArt;
aw->arts->commonInfo->src.art = art;
aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art);
aw->arts->markPossibleSlots(movedArt);
aw->arts->markPossibleSlots(art);
//aw->arts->commonInfo->dst.AOH = aw->arts;
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[movedArt->artType->id].bitmap);
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[art->artType->id].bitmap);
aw->arts->artifactsOnAltar.erase(movedArt);
aw->arts->artifactsOnAltar.erase(art);
id = -1;
subtitle = "";
aw->deal->block(!aw->arts->artifactsOnAltar.size());
@ -2788,25 +2786,25 @@ const CArtifactInstance * CTradeWindow::CTradeableItem::getArtInstance() const
}
}
const CArtifact * CTradeWindow::CTradeableItem::getArt() const
{
return NULL;
}
void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) const
{
}
void CTradeWindow::CTradeableItem::setArt(const CArtifact *artT) const
{
}
// const CArtifact * CTradeWindow::CTradeableItem::getArt() const
// {
// return NULL;
// }
//
// void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) const
// {
//
// }
//
// void CTradeWindow::CTradeableItem::setArt(const CArtifact *artT) const
// {
//
// }
CTradeWindow::CTradeWindow(const IMarket *Market, const CGHeroInstance *Hero, EMarketMode Mode)
: market(Market), hero(Hero), arts(NULL), hLeft(NULL), hRight(NULL), readyToTrade(false)
{
type = BLOCK_ADV_HOTKEYS;
type |= BLOCK_ADV_HOTKEYS;
mode = Mode;
initTypes();
}
@ -3537,6 +3535,7 @@ CAltarWindow::CAltarWindow(const IMarket *Market, const CGHeroInstance *Hero /*=
arts->recActions = 255;
arts->allowedAssembling = false;
addChild(arts);
artSets.push_back(arts);
}
initItems(false);
@ -3873,6 +3872,7 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
arts->artifactsOnAltar.insert(art);
altarSlot->id = artID;
altarSlot->subtitle = boost::lexical_cast<std::string>(val);
altarSlot->hlp = art;
deal->block(false);
return true;
@ -3880,14 +3880,23 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
void CAltarWindow::moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, const CArtifactInstance *art)
{
int freeBackpackSlot = hero->artifactsInBackpack.size() + Arts::BACKPACK_START;
if(arts->commonInfo->src.art)
{
arts->commonInfo->dst.slotID = 65500;
arts->commonInfo->dst.slotID = freeBackpackSlot;
arts->commonInfo->dst.AOH = arts;
}
if(putOnAltar(altarSlot, art))
LOCPLINT->cb->swapArtifacts(hero, slotID, hero, 65500);
{
if(slotID < Arts::BACKPACK_START)
LOCPLINT->cb->swapArtifacts(hero, slotID, hero, freeBackpackSlot);
else
{
arts->commonInfo->src.clear();
arts->commonInfo->dst.clear();
}
}
}
CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface * owner)
@ -4536,6 +4545,11 @@ CRClickPopupInt::~CRClickPopupInt()
CCS->curh->show();
}
void CRClickPopupInt::showAll(SDL_Surface * to)
{
inner->showAll(to);
}
CArtPlace::CArtPlace(const CArtifactInstance* Art)
: marked(false), ourArt(Art), picked(false), locked(false)
{
@ -4704,7 +4718,7 @@ void CArtPlace::select ()
return;
picked = true;
//int backpackCorrection = -(slotID - 19 < ourOwner->backpackPos);
//int backpackCorrection = -(slotID - Arts::BACKPACK_START < ourOwner->backpackPos);
CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[ourArt->artType->id].bitmap);
ourOwner->commonInfo->src.setTo(this, false);
@ -5297,9 +5311,18 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
tlog1 << "Unexpected artifact movement...\n";
}
int shift = 0;
// if(dst.slot >= Arts::BACKPACK_START && dst.slot - Arts::BACKPACK_START < backpackPos)
// shift++;
//
if(src.slot < Arts::BACKPACK_START && dst.slot - Arts::BACKPACK_START < backpackPos)
shift++;
if(dst.slot < Arts::BACKPACK_START && src.slot - Arts::BACKPACK_START < backpackPos)
shift--;
if( src.hero == curHero && src.slot >= Arts::BACKPACK_START
|| dst.hero == curHero && dst.slot >= Arts::BACKPACK_START)
scrollBackpack(0); //update backpack slots
scrollBackpack(shift); //update backpack slots
}
CArtPlace * CArtifactsOfHero::getArtPlace(int slot)

View File

@ -130,6 +130,7 @@ public:
bool delInner;
void show(SDL_Surface * to);
void showAll(SDL_Surface * to);
CRClickPopupInt(IShowActivable *our, bool deleteInt); //c-tor
virtual ~CRClickPopupInt(); //d-tor
};
@ -580,7 +581,16 @@ public:
void showAll(SDL_Surface * to);
};
class CTradeWindow : public CIntObject //base for markets and altar of sacrifice
class CWindowWithArtifacts : public virtual CIntObject
{
public:
std::vector<CArtifactsOfHero *> artSets;
CWindowWithArtifacts();
~CWindowWithArtifacts();
};
class CTradeWindow : public CWindowWithArtifacts //base for markets and altar of sacrifice
{
public:
enum EType
@ -596,12 +606,11 @@ public:
bool left;
std::string subtitle; //empty if default
void *hlp; //holds ptr to artifact instance id type artifact
const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact
const CArtifactInstance *getArtInstance() const;
const CArtifact *getArt() const;
void setArtInstance(const CArtifactInstance *art) const;
void setArt(const CArtifact *artT) const;
// const CArtifact *getArt() const;
// void setArtInstance(const CArtifactInstance *art) const;
// void setArt(const CArtifact *artT) const;
CFunctionList<void()> callback;
bool downSelection;
@ -909,15 +918,6 @@ public:
void show(SDL_Surface * to);
};
class CWindowWithArtifacts : public virtual CIntObject
{
public:
std::vector<CArtifactsOfHero *> artSets;
CWindowWithArtifacts();
~CWindowWithArtifacts();
};
class CArtPlace: public LRClickableAreaWTextComp
{
public:

View File

@ -51,73 +51,73 @@ bool CArtifact::isBig () const
{
return VLC->arth->isBigArtifact(id);
}
//
// bool CArtifact::isModable () const
// {
// return (bool)dynamic_cast<const IModableArt *>(this);
// }
bool CArtifact::isModable () const
{
return (bool)dynamic_cast<const IModableArt *>(this);
}
/**
* Checks whether the artifact fits at a given slot.
* @param artifWorn A hero's set of worn artifacts.
*/
bool CArtifact::fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
{
if (!vstd::contains(possibleSlots, slotID))
return false;
// Can't put an artifact in a locked slot.
std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.find(slotID);
if (it != artifWorn.end() && it->second->id == 145)
return false;
// Check if a combination artifact fits.
// TODO: Might want a more general algorithm?
// Assumes that misc & rings fits only in their slots, and others in only one slot and no duplicates.
if (constituents != NULL)
{
std::map<ui16, const CArtifact*> tempArtifWorn = artifWorn;
const ui16 ringSlots[] = {6, 7};
const ui16 miscSlots[] = {9, 10, 11, 12, 18};
int rings = 0;
int misc = 0;
VLC->arth->unequipArtifact(tempArtifWorn, slotID);
BOOST_FOREACH(ui32 constituentID, *constituents)
{
const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
const int slot = constituent.possibleSlots[0];
if (slot == 6 || slot == 7)
rings++;
else if ((slot >= 9 && slot <= 12) || slot == 18)
misc++;
else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
return false;
}
// Ensure enough ring slots are free
for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++)
{
if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
rings--;
}
if (rings > 0)
return false;
// Ensure enough misc slots are free.
for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++)
{
if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
misc--;
}
if (misc > 0)
return false;
}
return true;
}
// /**
// * Checks whether the artifact fits at a given slot.
// * @param artifWorn A hero's set of worn artifacts.
// */
// bool CArtifact::fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
// {
// if (!vstd::contains(possibleSlots, slotID))
// return false;
//
// // Can't put an artifact in a locked slot.
// std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.find(slotID);
// if (it != artifWorn.end() && it->second->id == 145)
// return false;
//
// // Check if a combination artifact fits.
// // TODO: Might want a more general algorithm?
// // Assumes that misc & rings fits only in their slots, and others in only one slot and no duplicates.
// if (constituents != NULL)
// {
// std::map<ui16, const CArtifact*> tempArtifWorn = artifWorn;
// const ui16 ringSlots[] = {6, 7};
// const ui16 miscSlots[] = {9, 10, 11, 12, 18};
// int rings = 0;
// int misc = 0;
//
// VLC->arth->unequipArtifact(tempArtifWorn, slotID);
//
// BOOST_FOREACH(ui32 constituentID, *constituents)
// {
// const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
// const int slot = constituent.possibleSlots[0];
//
// if (slot == 6 || slot == 7)
// rings++;
// else if ((slot >= 9 && slot <= 12) || slot == 18)
// misc++;
// else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
// return false;
// }
//
// // Ensure enough ring slots are free
// for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++)
// {
// if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
// rings--;
// }
// if (rings > 0)
// return false;
//
// // Ensure enough misc slots are free.
// for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++)
// {
// if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
// misc--;
// }
// if (misc > 0)
// return false;
// }
//
// return true;
// }
// bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
// {
@ -189,11 +189,11 @@ std::string CArtifact::nodeName() const
// }
// }
void CScroll::Init()
{
// addNewBonus (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
// //boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
}
// void CScroll::Init()
// {
// // addNewBonus (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
// // //boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
// }
CArtHandler::CArtHandler()
{
@ -202,7 +202,7 @@ CArtHandler::CArtHandler()
// War machines are the default big artifacts.
for (ui32 i = 3; i <= 6; i++)
bigArtifacts.insert(i);
modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
//modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
}
CArtHandler::~CArtHandler()
@ -231,24 +231,24 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
std::map<ui32,ui8>::iterator itr;
for (int i=0; i<ARTIFACTS_QUANTITY; i++)
{
CArtifact *art;
if ((itr = modableArtifacts.find(i)) != modableArtifacts.end())
{
switch (itr->second)
{
case 1:
art = new CScroll;
break;
case 2:
art = new CCustomizableArt;
break;
case 3:
art = new CCommanderArt;
break;
};
}
else
art = new CArtifact;
CArtifact *art = new CArtifact();
// if ((itr = modableArtifacts.find(i)) != modableArtifacts.end())
// {
// switch (itr->second)
// {
// case 1:
// art = new CScroll;
// break;
// case 2:
// art = new CCustomizableArt;
// break;
// case 3:
// art = new CCommanderArt;
// break;
// };
// }
// else
// art = new CArtifact;
CArtifact &nart = *art;
nart.id=i;
@ -754,95 +754,95 @@ void CArtHandler::clear()
}
/**
* Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
* Does not test if the operation is legal.
* @param artifWorn A hero's set of worn artifacts.
* @param bonuses Optional list of bonuses to update.
*/
void CArtHandler::equipArtifact( std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art ) const
{
unequipArtifact(artifWorn, slotID);
if (art) //false when artifact is NULL -> slot set to empty
{
const CArtifact &artifact = *art;
// Add artifact.
artifWorn[slotID] = art;
// Add locks, in reverse order of being removed.
if (artifact.constituents != NULL)
{
bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
{
const CArtifact &constituent = *artifacts[constituentID];
if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
{
destConsumed = true;
}
else
{
BOOST_FOREACH(ui16 slot, constituent.possibleSlots)
{
if (!vstd::contains(artifWorn, slot))
{
artifWorn[slot] = VLC->arth->artifacts[145]; //lock
break;
}
}
}
}
}
}
}
/**
* Locally unequips an artifact from a hero's worn slots.
* Does not test if the operation is legal.
* @param artifWorn A hero's set of worn artifacts.
* @param bonuses Optional list of bonuses to update.
*/
void CArtHandler::unequipArtifact(std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
{
if (!vstd::contains(artifWorn, slotID))
return;
const CArtifact &artifact = *artifWorn[slotID];
// Remove artifact, if it's not already removed.
artifWorn.erase(slotID);
// Remove locks, in reverse order of being added.
if (artifact.constituents != NULL)
{
bool destConsumed = false;
BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
{
const CArtifact &constituent = *artifacts[constituentID];
if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
{
destConsumed = true;
}
else
{
BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots)
{
if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145)
{
artifWorn.erase(slot);
break;
}
}
}
}
}
}
// /**
// * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
// * Does not test if the operation is legal.
// * @param artifWorn A hero's set of worn artifacts.
// * @param bonuses Optional list of bonuses to update.
// */
// void CArtHandler::equipArtifact( std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art ) const
// {
// unequipArtifact(artifWorn, slotID);
//
// if (art) //false when artifact is NULL -> slot set to empty
// {
// const CArtifact &artifact = *art;
//
// // Add artifact.
// artifWorn[slotID] = art;
//
// // Add locks, in reverse order of being removed.
// if (artifact.constituents != NULL)
// {
// bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
// {
// const CArtifact &constituent = *artifacts[constituentID];
//
// if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
// {
// destConsumed = true;
// }
// else
// {
// BOOST_FOREACH(ui16 slot, constituent.possibleSlots)
// {
// if (!vstd::contains(artifWorn, slot))
// {
// artifWorn[slot] = VLC->arth->artifacts[145]; //lock
// break;
// }
// }
// }
// }
// }
// }
// }
//
// /**
// * Locally unequips an artifact from a hero's worn slots.
// * Does not test if the operation is legal.
// * @param artifWorn A hero's set of worn artifacts.
// * @param bonuses Optional list of bonuses to update.
// */
// void CArtHandler::unequipArtifact(std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
// {
// if (!vstd::contains(artifWorn, slotID))
// return;
//
// const CArtifact &artifact = *artifWorn[slotID];
//
// // Remove artifact, if it's not already removed.
// artifWorn.erase(slotID);
//
// // Remove locks, in reverse order of being added.
// if (artifact.constituents != NULL)
// {
// bool destConsumed = false;
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
// {
// const CArtifact &constituent = *artifacts[constituentID];
//
// if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
// {
// destConsumed = true;
// }
// else
// {
// BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots)
// {
// if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145)
// {
// artifWorn.erase(slot);
// break;
// }
// }
// }
// }
// }
// }
void CArtHandler::clearHlpLists()
{
@ -1023,8 +1023,30 @@ CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
bool CCombinedArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const
{
return CArtifactInstance::canBePutAt(al, assumeDestRemoved);
//TODO look for place for constituents
bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(al, assumeDestRemoved);
if(!canMainArtifactBePlaced)
return false; //no is no...
if(al.slot >= Arts::BACKPACK_START)
return true; //we can always remove combined art to the backapck
assert(artType->constituents);
std::vector<ConstituentInfo> constituentsToBePlaced = constituentsInfo; //we'll remove constituents from that list, as we find a suitable slot for them
//we iterate over all active slots and check if constituents fits them
for (int i = 0; i < Arts::BACKPACK_START; i++)
{
for(std::vector<ConstituentInfo>::iterator art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
{
if(art->art->canBePutAt(ArtifactLocation(al.hero, i), i == al.slot)) // i == al.slot because we can remove already worn artifact only from that slot that is our main destination
{
constituentsToBePlaced.erase(art);
break;
}
}
}
return constituentsToBePlaced.empty();
}
bool CCombinedArtifactInstance::canBeDisassembled() const
@ -1058,7 +1080,7 @@ void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, int slo
assert(vstd::contains(*artType->constituents, art->artType->id));
assert(art->parents.size() == 1 && art->parents.front() == art->artType);
constituentsInfo.push_back(ConstituentInfo(art, slot));
art->attachTo(this);
attachTo(art);
}
void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)

View File

@ -30,11 +30,11 @@ public:
const std::string &Name() const; //getter
const std::string &Description() const; //getter
bool isBig () const;
bool isModable () const;
bool fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slot) const;
//bool isModable () const;
//bool fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slot) const;
//bool canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const;
void addBonusesTo (BonusList *otherBonuses) const;
void removeBonusesFrom (BonusList *otherBonuses) const;
// void addBonusesTo (BonusList *otherBonuses) const;
// void removeBonusesFrom (BonusList *otherBonuses) const;
virtual void SetProperty (int mod){};
virtual void Init(){};
int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
@ -136,61 +136,61 @@ public:
}
};
class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
{ //used only for dynamic cast :P
public:
si32 ID; //used for smart serialization
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArtifact&>(*this);
h & ID;
}
};
class DLL_EXPORT CScroll : public IModableArt // Spell Scroll
{
public:
CScroll(){spellid=0;};
CScroll(spelltype sid){spellid = sid;};
spelltype spellid;
void Init();
void SetProperty (int mod){spellid = mod;};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<IModableArt&>(*this);
h & spellid;
}
};
class DLL_EXPORT CCustomizableArt : public IModableArt // Warlord's Banner with multiple options
{
public:
ui8 mode;
CCustomizableArt(){mode=0;};
void Init(){};
void SetProperty (int mod){};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<IModableArt&>(*this);
h & mode;
}
};
class DLL_EXPORT CCommanderArt : public IModableArt // Growing with time
{
public:
ui32 level;
CCommanderArt(){level = 0;};
void Init(){};
void SetProperty (int mod){level = mod;};
void Upgrade(){level++;};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<IModableArt&>(*this);
h & level;
}
};
// class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner
// { //used only for dynamic cast :P
// public:
// si32 ID; //used for smart serialization
//
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & static_cast<CArtifact&>(*this);
// h & ID;
// }
// };
//
// class DLL_EXPORT CScroll : public IModableArt // Spell Scroll
// {
// public:
// CScroll(){spellid=0;};
// CScroll(spelltype sid){spellid = sid;};
// spelltype spellid;
// void Init();
// void SetProperty (int mod){spellid = mod;};
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & static_cast<IModableArt&>(*this);
// h & spellid;
// }
// };
//
// class DLL_EXPORT CCustomizableArt : public IModableArt // Warlord's Banner with multiple options
// {
// public:
// ui8 mode;
// CCustomizableArt(){mode=0;};
// void Init(){};
// void SetProperty (int mod){};
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & static_cast<IModableArt&>(*this);
// h & mode;
// }
// };
//
// class DLL_EXPORT CCommanderArt : public IModableArt // Growing with time
// {
// public:
// ui32 level;
// CCommanderArt(){level = 0;};
// void Init(){};
// void SetProperty (int mod){level = mod;};
// void Upgrade(){level++;};
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & static_cast<IModableArt&>(*this);
// h & level;
// }
// };
class DLL_EXPORT CArtHandler //handles artifacts
{
@ -200,7 +200,7 @@ public:
std::vector< ConstTransitivePtr<CArtifact> > artifacts;
std::vector<CArtifact *> allowedArtifacts;
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
//std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
void loadArtifacts(bool onlyTxt);
void sortArts();
@ -213,8 +213,8 @@ public:
void getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags);
void erasePickedArt (si32 id);
bool isBigArtifact (ui32 artID) const {return bigArtifacts.find(artID) != bigArtifacts.end();}
void equipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art) const;
void unequipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const;
// void equipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art) const;
// void unequipArtifact (std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const;
void initAllowedArtifactsList(const std::vector<ui8> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
static int convertMachineID(int id, bool creToArt);
CArtHandler();

View File

@ -306,19 +306,18 @@ CCreatureSet::~CCreatureSet()
clear();
}
void CCreatureSet::setToArmy(CCreatureSet &src)
void CCreatureSet::setToArmy(CSimpleArmy &src)
{
clear();
while(src)
{
TSlots::iterator i = src.stacks.begin();
TSimpleSlots::iterator i = src.army.begin();
assert(i->second->type);
assert(i->second->valid(false));
assert(i->second->armyObj == NULL);
assert(i->second.type);
assert(i->second.count);
putStack(i->first, i->second);
src.stacks.erase(i);
putStack(i->first, new CStackInstance(i->second.type, i->second.count));
src.army.erase(i);
}
}
@ -523,4 +522,21 @@ DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance &
str << sth.idRand;
return str;
}
void CSimpleArmy::clear()
{
army.clear();
}
CSimpleArmy::operator bool() const
{
return army.size();
}
bool CSimpleArmy::setCreature(TSlot slot, TCreature cre, TQuantity count)
{
assert(!vstd::contains(army, slot));
army[slot] = CStackBasicDescriptor(cre, count);
return true;
}

View File

@ -64,10 +64,31 @@ public:
DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance & sth);
typedef std::map<TSlot, CStackInstance*> TSlots;
typedef std::map<TSlot, CStackBasicDescriptor> TSimpleSlots;
class IArmyDescriptor
{
public:
virtual void clear() = 0;
virtual bool setCreature(TSlot slot, TCreature cre, TQuantity count) = 0;
};
//simplified version of CCreatureSet
class DLL_EXPORT CSimpleArmy : public IArmyDescriptor
{
public:
TSimpleSlots army;
void clear() OVERRIDE;
bool setCreature(TSlot slot, TCreature cre, TQuantity count) OVERRIDE;
operator bool() const;
class DLL_EXPORT CCreatureSet //seven combined creatures
template <typename Handler> void serialize(Handler &h, const int version)
{
h & army;
}
};
class DLL_EXPORT CCreatureSet : public IArmyDescriptor //seven combined creatures
{
CCreatureSet(const CCreatureSet&);;
CCreatureSet &operator=(const CCreatureSet&);
@ -84,7 +105,7 @@ public:
void addToSlot(TSlot slot, TCreature cre, TQuantity count, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
void addToSlot(TSlot slot, CStackInstance *stack, bool allowMerging = true); //Adds stack to slot. Slot must be empty or with same type creature
void clear();
void clear() OVERRIDE;
void setFormation(bool tight);
CArmedInstance *castToArmyObj();
@ -98,8 +119,8 @@ public:
//derivative
void changeStackCount(TSlot slot, TQuantity toAdd); //stack must exist!
bool setCreature (TSlot slot, TCreature type, TQuantity quantity); //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
void setToArmy(CCreatureSet &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
bool setCreature (TSlot slot, TCreature type, TQuantity quantity) OVERRIDE; //replaces creature in stack; slots 0 to 6, if quantity=0 erases stack
void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
const CStackInstance& getStack(TSlot slot) const;
const CCreature* getCreature(TSlot slot) const; //workaround of map issue;

View File

@ -836,7 +836,7 @@ void CGHeroInstance::initHero()
mana = manaLimit();
}
void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
{
if(!dst)
dst = this;
@ -883,7 +883,7 @@ void CGHeroInstance::initArmy(CCreatureSet *dst /*= NULL*/)
tlog3 << "Hero " << name << " already has artifact at " << slot << ", ommiting giving " << aid << std::endl;
}
else
dst->putStack(stackNo-warMachinesGiven, new CStackInstance(creID, count));
dst->setCreature(stackNo-warMachinesGiven, creID, count);
}
}
void CGHeroInstance::initHeroDefInfo()

View File

@ -418,7 +418,7 @@ public:
void putArtifact(ui16 pos, CArtifactInstance *art);
void putInBackpack(CArtifactInstance *art);
void initExp();
void initArmy(CCreatureSet *dst = NULL);
void initArmy(IArmyDescriptor *dst = NULL);
void giveArtifact (ui32 aid);
void initHeroDefInfo();
void pushPrimSkill(int which, int val);

View File

@ -438,6 +438,8 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & bonuses & nodeType;
h & exportedBonuses;
//h & parents & children;
}
enum ENodeTypes

View File

@ -368,19 +368,17 @@ struct SetAvailableHeroes : public CPackForClient //113
{
type = 113;
for (int i = 0; i < AVAILABLE_HEROES_PER_PLAYER; i++)
army[i] = NULL;
army[i].clear();
}
~SetAvailableHeroes()
{
for (int i = 0; i < AVAILABLE_HEROES_PER_PLAYER; i++)
delete army[i];
}
void applyCl(CClient *cl);
DLL_EXPORT void applyGs(CGameState *gs);
ui8 player;
si32 hid[AVAILABLE_HEROES_PER_PLAYER]; //-1 if no hero
CCreatureSet *army[AVAILABLE_HEROES_PER_PLAYER];
CSimpleArmy army[AVAILABLE_HEROES_PER_PLAYER];
template <typename Handler> void serialize(Handler &h, const int version)
{
h & player & hid & army;

View File

@ -180,7 +180,7 @@ DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
{
CGHeroInstance *h = (hid[i]>=0 ? (CGHeroInstance*)gs->hpool.heroesPool[hid[i]] : NULL);
if(h && army[i])
h->setToArmy(*army[i]);
h->setToArmy(army[i]);
p->availableHeroes.push_back(h);
}
}
@ -729,6 +729,7 @@ DLL_EXPORT void AssembledArtifact::applyGs( CGameState *gs )
assert(vstd::contains(transformedArt->assemblyPossibilities(al.hero), builtArt));
CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
gs->map->addNewArtifactInstance(combinedArt);
//retreive all constituents
BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
{
@ -739,6 +740,8 @@ DLL_EXPORT void AssembledArtifact::applyGs( CGameState *gs )
//move constituent from hero to be part of new, combined artifact
constituentInstance->removeFrom(h, pos);
combinedArt->addAsConstituent(constituentInstance, pos);
if(!vstd::contains(combinedArt->artType->possibleSlots, al.slot) && vstd::contains(combinedArt->artType->possibleSlots, pos))
al.slot = pos;
}
//put new combined artifacts
@ -755,11 +758,11 @@ DLL_EXPORT void DisassembledArtifact::applyGs( CGameState *gs )
disassembled->removeFrom(h, al.slot);
BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, constituents)
{
ci.art->detachFrom(disassembled);
disassembled->detachFrom(ci.art);
ci.art->putAt(h, ci.slot >= 0 ? ci.slot : al.slot); //-1 is slot of main constituent -> it'll replace combined artifact in its pos
}
delNull(disassembled);
gs->map->eraseArtifactInstance(disassembled);
}
DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )

View File

@ -80,6 +80,17 @@ void registerTypes1(Serializer &s)
s.template registerType<CreatureFactionLimiter>();
s.template registerType<CreatureAlignmentLimiter>();
s.template registerType<CBonusSystemNode>();
s.template registerType<CArtifact>();
s.template registerType<CCreature>();
s.template registerType<CStackInstance>();
s.template registerType<PlayerState>();
s.template registerType<TeamState>();
s.template registerType<CGameState>();
s.template registerType<CGHeroInstance::HeroSpecial>();
s.template registerType<CArmedInstance>();
s.template registerType<CStack>();
s.template registerType<BattleInfo>();
s.template registerType<CArtifactInstance>();
s.template registerType<CCombinedArtifactInstance>();
}

View File

@ -2097,6 +2097,12 @@ CArtifactInstance * Mapa::createArt(int aid)
return a;
}
void Mapa::eraseArtifactInstance(CArtifactInstance *art)
{
assert(artInstances[art->id] == art);
artInstances[art->id].dellNull();
}
LossCondition::LossCondition()
{
obj = NULL;

View File

@ -307,9 +307,10 @@ struct DLL_EXPORT Mapa : public CMapHeader
int loadSeerHut( const unsigned char * bufor, int i, CGObjectInstance *& nobj);
CArtifactInstance *createArt(int aid);
void addNewArtifactInstance(CArtifactInstance *art);
void eraseArtifactInstance(CArtifactInstance *art);
void checkForObjectives();
void addNewArtifactInstance(CArtifactInstance *art);
void addBlockVisTiles(CGObjectInstance * obj);
void removeBlockVisTiles(CGObjectInstance * obj, bool total=false);
Mapa(std::string filename); //creates map structure from .h3m file

View File

@ -430,8 +430,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
sah.hid[0] = loserHero->subID;
if(result == 1) //retreat
{
sah.army[0] = new CCreatureSet();
sah.army[0]->addToSlot(0, VLC->creh->nameToID[loserHero->type->refTypeStack[0]],1);
sah.army[0].clear();
sah.army[0].setCreature(0, VLC->creh->nameToID[loserHero->type->refTypeStack[0]],1);
}
if(const CGHeroInstance *another = getPlayerState(loser)->availableHeroes[1])
@ -799,7 +799,7 @@ void CGameHandler::newTurn()
if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, i->first, getNativeTown(i->first), pool, banned)) //first hero - native if possible, second hero -> any other class
{
sah.hid[j] = h->subID;
h->initArmy(sah.army[j] = new CCreatureSet());
h->initArmy(&sah.army[j]);
banned = h->type->heroClass;
}
else
@ -2994,8 +2994,8 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, ui8 player)
if(newHero)
{
sah.hid[hid] = newHero->subID;
sah.army[hid] = new CCreatureSet();
sah.army[hid]->addToSlot(0, VLC->creh->nameToID[newHero->type->refTypeStack[0]],1);
sah.army[hid].clear();
sah.army[hid].setCreature(0, VLC->creh->nameToID[newHero->type->refTypeStack[0]],1);
}
else
sah.hid[hid] = -1;