diff --git a/CCallback.cpp b/CCallback.cpp index 0bdea91c4..1a4bdc333 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -134,7 +134,7 @@ bool CCallback::swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IAr const CGHeroInstance * hero1 = dynamic_cast(src); const CGHeroInstance * hero2 = dynamic_cast(dest); - ExchangeArtifacts ea; + ExchangeArtifacts ea(0,0,0,0); if (hero1 && hero2) { diff --git a/client/CCreatureWindow.cpp b/client/CCreatureWindow.cpp index 278bf356a..d68d577c4 100644 --- a/client/CCreatureWindow.cpp +++ b/client/CCreatureWindow.cpp @@ -251,14 +251,17 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode * } } - if (GameConstants::STACK_ARTIFACT && type > BATTLE) + if (GameConstants::STACK_ARTIFACT) { - //SDL_Rect rect = genRect(44,44,465,98); - //creatureArtifact = new CArtPlace(NULL); - //creatureArtifact->pos = rect; - //creatureArtifact->ourOwner = NULL; //hmm? - leftArtRoll = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, -1), 437, 98, "hsbtns3.def", SDLK_LEFT); - rightArtRoll = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, +1), 516, 98, "hsbtns5.def", SDLK_RIGHT); + if (type > BATTLE) //artifact buttons inactive in battle + { + leftArtRoll = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, -1), 437, 98, "hsbtns3.def", SDLK_LEFT); + rightArtRoll = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, +1), 516, 98, "hsbtns5.def", SDLK_RIGHT); + if (heroOwner) + passArtToHero = new CAdventureMapButton(std::string(), std::string(), boost::bind (&CCreatureWindow::scrollArt, this, 0), 437, 148, "OVBUTN1.DEF", SDLK_HOME); + } + if (ConstTransitivePtr art = stack->activeArtifact.artifact) + blitAt(graphics->artDefs->ourImages[art->id].bitmap, 466, 161, *bitmap); } else creatureArtifact = NULL; diff --git a/client/CCreatureWindow.h b/client/CCreatureWindow.h index 97401c7bc..de83c0bcb 100644 --- a/client/CCreatureWindow.h +++ b/client/CCreatureWindow.h @@ -60,7 +60,7 @@ public: CSlider * slider; //Abilities CAdventureMapButton *dismiss, *upgrade, *ok; CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection - //TODO: Artifact drop + CAdventureMapButton * passArtToHero; boost::function dsm; //dismiss button callback boost::function Upg; //upgrade button callback diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 10f267558..6e87a8383 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -273,19 +273,18 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState) { artSelected = true; if (art->canBePutAt(ArtifactLocation(myStack, GameConstants::CREATURE_ART))) - { - //TODO : move + { //equip clicked stack + LOCPLINT->cb->swapArtifacts(aoh->getHero(), aoh->commonInfo->src.slotID, myStack, GameConstants::CREATURE_ART); break; } } } } - if (!artSelected) + if (artSelected || creature) { + owner->highlighted = this; if(creature) { - owner->highlighted = this; - for(size_t i = 0; isplitButtons.size(); i++) owner->splitButtons[i]->block(false); } @@ -5071,7 +5070,8 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact if(commonInfo->src == src) //artifact was taken from us { - assert(commonInfo->dst == dst || dst.slot == dst.hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START); + //assert(commonInfo->dst == dst || dst.slot == dst.hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START); + //FIXME: assertion fails for stack artifacts commonInfo->reset(); unmarkSlots(); } diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 30364ad67..ba0d9ca49 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -216,8 +216,9 @@ void EraseArtifact::applyCl( CClient *cl ) void MoveArtifact::applyCl( CClient *cl ) { INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst); - if(src.hero->tempOwner != dst.hero->tempOwner) - INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst); + if (src.hero.get() && dst.hero.get()) + if(src.hero->tempOwner != dst.hero->tempOwner) + INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst); } void AssembledArtifact::applyCl( CClient *cl ) diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 6e84aa6e6..46ac57a30 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -1277,7 +1277,7 @@ bool CCreatureArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assu { if (al.stack) { - return true; //all artifacts should fit on creature + return al.stack->isPositionFree(al.slot, assumeDestRemoved); } else if(al.slot >= GameConstants::BACKPACK_START) { //TODO backpack limit? @@ -1438,10 +1438,9 @@ void CArtifactSet::eraseArtSlot(ui16 slot) ArtSlotInfo & CCreatureArtifactSet::retreiveNewArtSlot(ui16 slot) { - assert(slot); //ke? - ArtSlotInfo &ret = slot <= GameConstants::CREATURE_ART + ArtSlotInfo &ret = slot == GameConstants::CREATURE_ART ? activeArtifact - : *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - 1), ArtSlotInfo()); + : *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - GameConstants::CREATURE_ART), ArtSlotInfo()); return ret; } @@ -1479,9 +1478,6 @@ si32 CCreatureArtifactSet::getArtPos(int aid, bool onlyWorn) const if (aid == activeArtifact.artifact->artType->id ) return GameConstants::CREATURE_ART; - if(onlyWorn) - return -1; - for(int i = 0; i < artifactsInBackpack.size(); i++) { if(artifactsInBackpack[i].artifact->artType->id == aid) @@ -1498,7 +1494,7 @@ si32 CCreatureArtifactSet::getArtPos(const CArtifactInstance *art) const for(int i = 0; i < artifactsInBackpack.size(); i++) if(artifactsInBackpack[i].artifact == art) - return GameConstants::BACKPACK_START + i; + return i + 1; return -1; } diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 71d55cd54..fd7a6a6f3 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -87,7 +87,7 @@ namespace GameConstants const ui16 BACKPACK_START = 19; const int ID_CATAPULT = 3, ID_LOCK = 145; - const ui16 CREATURE_ART = 0; + const ui16 CREATURE_ART = 0; //position in CCreatureArtifactSet //game modules const bool STACK_EXP = true; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 315cbb001..f6d159cde 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1758,7 +1758,10 @@ struct ExchangeArtifacts : public CPackForServer { ExchangeArtifacts(){}; ExchangeArtifacts(si32 H1, si32 H2, ui16 S1, ui16 S2) - :hid1(H1),hid2(H2),slot1(S1),slot2(S2){}; + :hid1(H1),hid2(H2),slot1(S1),slot2(S2) + { + s1 = s2 = StackLocation(NULL,0); + }; si32 hid1, hid2; StackLocation s1, s2; //for creature stacks ui16 slot1, slot2; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 8916365d2..6867f7261 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -560,7 +560,10 @@ DLL_LINKAGE CArtifactInstance *ArtifactLocation::getArt() DLL_LINKAGE const ArtSlotInfo *ArtifactLocation::getSlot() const { - return hero->getSlot(slot); + if (hero) + return hero->getSlot(slot); + if (stack) + return stack->getSlot(slot); } DLL_LINKAGE void ChangeStackCount::applyGs( CGameState *gs ) diff --git a/lib/RegisterTypes.h b/lib/RegisterTypes.h index 026ea00d4..001111d4c 100644 --- a/lib/RegisterTypes.h +++ b/lib/RegisterTypes.h @@ -95,6 +95,8 @@ void registerTypes1(Serializer &s) s.template registerType(); s.template registerType(); s.template registerType(); + //s.template registerType(); + //s.template registerType(); } template diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 03cd2b2e5..6e848f8c3 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2571,14 +2571,12 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u return true; } - bool CGameHandler::moveArtifact(StackLocation s1, StackLocation s2, ui16 srcSlot, ui16 destSlot) { ArtifactLocation src(s1.getStack(), srcSlot), dst(s2.getStack(), destSlot); moveArtifact(src, dst); return true; } - bool CGameHandler::moveArtifact(si32 srcHeroID, StackLocation s2, ui16 srcSlot, ui16 destSlot) { ArtifactLocation src(getHero(srcHeroID), srcSlot); @@ -2595,7 +2593,6 @@ bool CGameHandler::moveArtifact(StackLocation s1, si32 destHeroID, ui16 srcSlot, moveArtifact(src, dst); return true; } - void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) { MoveArtifact ma; @@ -2604,8 +2601,6 @@ void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocat sendAndApply(&ma); } - - /** * Assembles or disassembles a combination artifact. * @param heroID ID of hero holding the artifact(s). @@ -4356,27 +4351,32 @@ bool CGameHandler::isAllowedExchange( int id1, int id2 ) return true; const CGObjectInstance *o1 = getObj(id1), *o2 = getObj(id2); - - if(o1->ID == GameConstants::TOWNI_TYPE) + if (o1 && o2) { - const CGTownInstance *t = static_cast(o1); - if(t->visitingHero == o2 || t->garrisonHero == o2) + if(o1->ID == GameConstants::TOWNI_TYPE) + { + const CGTownInstance *t = static_cast(o1); + if(t->visitingHero == o2 || t->garrisonHero == o2) + return true; + } + if(o2->ID == GameConstants::TOWNI_TYPE) + { + const CGTownInstance *t = static_cast(o2); + if(t->visitingHero == o1 || t->garrisonHero == o1) + return true; + } + if(o1->ID == GameConstants::HEROI_TYPE && o2->ID == GameConstants::HEROI_TYPE + && distance(o1->pos, o2->pos) < 2) //hero stands on the same tile or on the neighbouring tiles + { + //TODO: it's workaround, we should check if first hero visited second and player hasn't closed exchange window + //(to block moving stacks for free [without visiting] between heroes) return true; + } } - if(o2->ID == GameConstants::TOWNI_TYPE) + else //not exchanging between heroes, TODO: more sophisticated logic { - const CGTownInstance *t = static_cast(o2); - if(t->visitingHero == o1 || t->garrisonHero == o1) - return true; + return true; } - if(o1->ID == GameConstants::HEROI_TYPE && o2->ID == GameConstants::HEROI_TYPE - && distance(o1->pos, o2->pos) < 2) //hero stands on the same tile or on the neighbouring tiles - { - //TODO: it's workaround, we should check if first hero visited second and player hasn't closed exchange window - //(to block moving stacks for free [without visiting] between heroes) - return true; - } - return false; } diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index b96871828..bed38abda 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -134,7 +134,20 @@ bool GarrisonHeroSwap::applyGh( CGameHandler *gh ) bool ExchangeArtifacts::applyGh( CGameHandler *gh ) { ERROR_IF_NOT_OWNS(hid1);//second hero can be ally - return gh->moveArtifact(hid1,hid2,slot1,slot2); + if (hid1) + { //TODO: polymorph + if (hid2) + return gh->moveArtifact(hid1,hid2,slot1,slot2); + else + return gh->moveArtifact(hid1,s2,slot1,slot2); + } + else + { + if (hid2) + return gh->moveArtifact(s1,hid2,slot1,slot2); + else + return gh->moveArtifact(s1,s2,slot1,slot2); + } } bool AssembleArtifacts::applyGh( CGameHandler *gh )