#include "PrecompiledHeader.h" #include "ActionLayer.h" #include "GameObserver.h" #include "Targetable.h" #include "WEvent.h" MTGAbility* ActionLayer::getAbility(int type) { for (int i = 1; i < mCount; i++) { MTGAbility * a = ((MTGAbility *) mObjects[i]); if (a->aType == type) { return a; } } return NULL; } int ActionLayer::moveToGarbage(ActionElement * e) { int i = getIndexOf(e); if (i != -1) { if (isWaitingForAnswer() == e) setCurrentWaitingAction(NULL); e->destroy(); mObjects.erase(mObjects.begin() + i); mCount--; garbage.push_back(e); return 1; } return 0; } int ActionLayer::cleanGarbage() { for (size_t i = 0; i < garbage.size(); ++i) { delete (garbage[i]); } garbage.clear(); return 1; } int ActionLayer::reactToClick(ActionElement * ability, MTGCardInstance * card) { int result = ability->reactToClick(card); if (result) stuffHappened = 1; return result; } int ActionLayer::reactToTargetClick(ActionElement* ability, Targetable * card) { int result = ability->reactToTargetClick(card); if (result) stuffHappened = 1; return result; } bool ActionLayer::CheckUserInput(JButton key) { GameObserver * g = GameObserver::GetInstance(); if (g->mExtraPayment && key == JGE_BTN_SEC) { g->mExtraPayment = NULL; return 1; } if (menuObject) { return false; } for (int i = 0; i < mCount; i++) { if (mObjects[i] != NULL) { ActionElement * currentAction = (ActionElement *) mObjects[i]; if (currentAction->CheckUserInput(key)) return true; } } return false; } void ActionLayer::Update(float dt) { stuffHappened = 0; if (menuObject) { abilitiesMenu->Update(dt); return; } modal = 0; GameObserver* game = GameObserver::GetInstance(); for (int i = mCount - 1; i >= 0; i--) { if (mObjects[i] != NULL) { ActionElement * currentAction = (ActionElement *) mObjects[i]; if (currentAction->testDestroy()) game->removeObserver(currentAction); } } int newPhase = game->getCurrentGamePhase(); for (int i = 0; i < mCount; i++) { if (mObjects[i] != NULL) { ActionElement * currentAction = (ActionElement *) mObjects[i]; currentAction->newPhase = newPhase; currentAction->Update(dt); currentAction->currentPhase = newPhase; } } if (cantCancel) { ActionElement * ae = isWaitingForAnswer(); if (ae && !ae->tc->validTargetsExist()) { cantCancel = 0; cancelCurrentAction(); } } } void ActionLayer::Render() { if (menuObject) { abilitiesMenu->Render(); return; } for (int i = 0; i < mCount; i++) { if (mObjects[i] != NULL) { ActionElement * currentAction = (ActionElement *) mObjects[i]; currentAction->Render(); } } } void ActionLayer::setCurrentWaitingAction(ActionElement * ae) { assert(!ae || !currentWaitingAction);//this assert causes crashes when may abilities overlap each other on ai. this conidiation is preexsiting. currentWaitingAction = ae; if (!ae) cantCancel = 0; } TargetChooser * ActionLayer::getCurrentTargetChooser() { if (currentWaitingAction && currentWaitingAction->waitingForAnswer) return currentWaitingAction->tc; return NULL; } int ActionLayer::cancelCurrentAction() { ActionElement * ae = isWaitingForAnswer(); if (!ae) return 0; if (cantCancel && ae->tc->validTargetsExist()) return 0; ae->waitingForAnswer = 0; //TODO MOVE THIS IN ActionElement setCurrentWaitingAction(NULL); return 1; } ActionElement * ActionLayer::isWaitingForAnswer() { if (currentWaitingAction && currentWaitingAction->waitingForAnswer) return currentWaitingAction; return NULL; } int ActionLayer::stillInUse(MTGCardInstance * card) { for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; if (currentAction->stillInUse(card)) return 1; } return 0; } int ActionLayer::receiveEventPlus(WEvent * event) { int result = 0; for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; result += currentAction->receiveEvent(event); } return 0; } int ActionLayer::isReactingToTargetClick(Targetable * card) { int result = 0; if (isWaitingForAnswer()) return -1; for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; result += currentAction->isReactingToTargetClick(card); } return result; } int ActionLayer::reactToTargetClick(Targetable * card) { int result = 0; ActionElement * ae = isWaitingForAnswer(); if (ae) return reactToTargetClick(ae, card); for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; result += currentAction->reactToTargetClick(card); } return result; } //TODO Simplify with only object !!! int ActionLayer::isReactingToClick(MTGCardInstance * card) { int result = 0; if (isWaitingForAnswer()) return -1; for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; result += currentAction->isReactingToClick(card); } return result; } int ActionLayer::reactToClick(MTGCardInstance * card) { int result = 0; ActionElement * ae = isWaitingForAnswer(); if (ae) return reactToClick(ae, card); for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; result += reactToClick(currentAction, card); if (result) return result; } return result; } void ActionLayer::setMenuObject(Targetable * object, bool must) { if (!object) { DebugTrace("FATAL: ActionLayer::setMenuObject"); return; } menuObject = object; SAFE_DELETE(abilitiesMenu); abilitiesMenu = NEW SimpleMenu(10, this, Fonts::MAIN_FONT, 100, 100, object->getDisplayName().c_str()); for (int i = 0; i < mCount; i++) { ActionElement * currentAction = (ActionElement *) mObjects[i]; if (currentAction->isReactingToTargetClick(object)) { abilitiesMenu->Add(i, currentAction->getMenuText()); } } if (!must) abilitiesMenu->Add(kCancelMenuID, "Cancel"); else cantCancel = 1; modal = 1; } void ActionLayer::doReactTo(int menuIndex) { if (menuObject) { int controlid = abilitiesMenu->mObjects[menuIndex]->GetId(); DebugTrace("ActionLayer::doReactTo " << controlid); ButtonPressed(0, controlid); } } void ActionLayer::ButtonPressed(int controllerid, int controlid) { if (controlid >= 0 && controlid < static_cast(mObjects.size())) { ActionElement * currentAction = (ActionElement *) mObjects[controlid]; currentAction->reactToTargetClick(menuObject); menuObject = 0; } else if (controlid == kCancelMenuID) { GameObserver::GetInstance()->mLayers->stackLayer()->endOfInterruption(); menuObject = 0; } else { // fallthrough case. We have an id we don't recognize - do nothing, don't clear the menu! //assert(false); } } ActionLayer::ActionLayer() { menuObject = NULL; abilitiesMenu = NULL; stuffHappened = 0; currentWaitingAction = NULL; cantCancel = 0; } ActionLayer::~ActionLayer() { for (int i = mCount - 1; i >= 0; i--) { moveToGarbage((ActionElement *) mObjects[i]); } SAFE_DELETE(abilitiesMenu); cleanGarbage(); }