diff --git a/projects/mtg/include/CardSelector.h b/projects/mtg/include/CardSelector.h index 1f8408172..27eb5aea7 100644 --- a/projects/mtg/include/CardSelector.h +++ b/projects/mtg/include/CardSelector.h @@ -2,6 +2,7 @@ #define _CARDSELECTOR_H_ #include +#include #include "GuiLayers.h" #include "DuelLayers.h" #include "Pos.h" @@ -26,6 +27,13 @@ class ObjectSelector : public GuiLayer typedef enum { nullZone, handZone, playZone } SelectorZone; + struct SelectorMemory + { + T* object; + float x, y; + SelectorMemory(T* object) : object(object) { if (object) { x = object->x; y = object->y; } }; + SelectorMemory() { object = NULL; x = y = 0; }; + }; protected: vector cards; @@ -34,7 +42,10 @@ class ObjectSelector : public GuiLayer DuelLayers* duel; LimitorFunctor* limitor; Pos bigpos; - map lasts; + map lasts; + stack memoryStack; + + T* fetchMemory(SelectorMemory&); public: ObjectSelector(DuelLayers*); @@ -44,6 +55,8 @@ class ObjectSelector : public GuiLayer void Update(float dt); void Render(); void Limit(LimitorFunctor* limitor); + void Push(); + void Pop(); typedef T Target; }; diff --git a/projects/mtg/src/CardSelector.cpp b/projects/mtg/src/CardSelector.cpp index 32fb26ac2..afa931a18 100644 --- a/projects/mtg/src/CardSelector.cpp +++ b/projects/mtg/src/CardSelector.cpp @@ -55,6 +55,46 @@ void CardSelector::Remove(CardSelector::Target* card) } } +template <> +CardSelector::Target* CardSelector::fetchMemory(SelectorMemory& memory) +{ + if (NULL == memory.object) return NULL; + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + { + if (*it == memory.object) + { + if ((NULL == limitor) || (limitor->select(memory.object))) + return memory.object; + else break; + } + } + // We come here if the card is not in the selector any more, or if + // it is there but it is now refused by the limitor. + return closest(cards, limitor, memory.x, memory.y); +} +template<> +void CardSelector::Push() +{ + memoryStack.push(SelectorMemory(active)); +} +template<> +void CardSelector::Pop() +{ + Target* oldactive = active; + if (!memoryStack.empty()) + { + active = fetchMemory(memoryStack.top()); + memoryStack.pop(); + } + if (active != oldactive) + { + { CardView* c = dynamic_cast(oldactive); if (c) c->zoom = 1.0; } + { CardView* c = dynamic_cast(active); if (c) c->zoom = 1.4; } + if (oldactive) oldactive->Leaving(0); + if (active) active->Entering(); + } +} + template<> bool CardSelector::CheckUserInput(u32 key) { @@ -102,16 +142,17 @@ bool CardSelector::CheckUserInput(u32 key) if (oldowner != owner) { if (nullZone != owner) - if (PlayGuiObject* old = lasts[owner]) active = old; - lasts[oldowner] = oldactive; + if (PlayGuiObject* old = fetchMemory(lasts[owner])) + active = old; + lasts[oldowner] = SelectorMemory(oldactive); } } if (active != oldactive) { { CardView* c = dynamic_cast(oldactive); if (c) c->zoom = 1.0; } { CardView* c = dynamic_cast(active); if (c) c->zoom = 1.4; } - oldactive->Leaving(key); - active->Entering(); + if (oldactive) oldactive->Leaving(0); + if (active) active->Entering(); } return true; } @@ -147,7 +188,15 @@ void CardSelector::Limit(LimitorFunctor* limitor) this->limitor = limitor; if (limitor && !limitor->select(active)) { + Target* oldactive = active; active = closest(cards, limitor, active); if (limitor && !limitor->select(active)) active = NULL; + if (active != oldactive) + { + { CardView* c = dynamic_cast(oldactive); if (c) c->zoom = 1.0; } + { CardView* c = dynamic_cast(active); if (c) c->zoom = 1.4; } + if (oldactive) oldactive->Leaving(0); + if (active) active->Entering(); + } } } diff --git a/projects/mtg/src/Closest.cpp b/projects/mtg/src/Closest.cpp index 56f497b95..36cd5b961 100644 --- a/projects/mtg/src/Closest.cpp +++ b/projects/mtg/src/Closest.cpp @@ -26,4 +26,23 @@ static inline Target* closest(vector& cards, Limitor* limitor, Target* return card; } +template +static inline Target* closest(vector& cards, Limitor* limitor, float x, float y) +{ + Target* card = NULL; + float curdist = 1000000.0f; // This is bigger than any possible distance + for (typename vector::iterator it = cards.begin(); it != cards.end(); ++it) + { + if ((*it)->actA < 32) continue; + if ((NULL != limitor) && (!limitor->select(*it))) continue; + float dist = ((*it)->x - x) * ((*it)->x - x) + ((*it)->y - y) * ((*it)->y - y); + if (dist < curdist) + { + curdist = dist; + card = *it; + } + } + return card; +} + #endif diff --git a/projects/mtg/src/Damage.cpp b/projects/mtg/src/Damage.cpp index c8f3f1e68..a24e02782 100644 --- a/projects/mtg/src/Damage.cpp +++ b/projects/mtg/src/Damage.cpp @@ -28,7 +28,7 @@ void Damage::init(MTGCardInstance * _source, Damageable * _target, int _damage){ int Damage::resolve(){ if (damage <0) damage = 0; //Negative damages cannot happen state = RESOLVED_OK; - + cout << "RESOLVE " << damage << " >> " << _target->name << endl; GameObserver * g = GameObserver::GetInstance(); WEvent * e = NEW WEventDamage(this); diff --git a/projects/mtg/src/GuiHand.cpp b/projects/mtg/src/GuiHand.cpp index 61f426bab..f88096218 100644 --- a/projects/mtg/src/GuiHand.cpp +++ b/projects/mtg/src/GuiHand.cpp @@ -112,7 +112,9 @@ bool GuiHandSelf::CheckUserInput(u32 key) if (trigger == key) { state = (Open == state ? Closed : Open); + if (Open == state) cs->Push(); cs->Limit(Open == state ? limitor : NULL); + if (Closed == state) cs->Pop(); backpos.x = Open == state ? OpenX : ClosedX; Repos(); return true; @@ -169,8 +171,8 @@ int GuiHandSelf::receiveEventMinus(WEvent* e) { CardView* cv = *it; cs->Remove(cv); - Repos(); cards.erase(it); + Repos(); trash(cv); return 1; }