- fixed a bug with Flagstones of Trokair. There was no easy fix (cloned objects deleting stuff from their parents...) and I ended up using a "garbage collect at end of turn" technique the way I did with the ActionStack. As a result, the memory print of a turn will become bigger, and even more bugs might occur at the end of a turn... I'm ready to discuss this, although I think it's the best solution (in terms of result/amount of work) given the way abilities work right now - Test suite now gives the number of failed/success at the end of the tests
280 lines
6.7 KiB
C++
280 lines
6.7 KiB
C++
#include "../include/config.h"
|
|
#include "../include/ActionLayer.h"
|
|
#include "../include/GameObserver.h"
|
|
#include "../include/Targetable.h"
|
|
#include "../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){
|
|
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;
|
|
}
|
|
|
|
int ActionLayer::unstoppableRenderInProgress(){
|
|
|
|
for (int i=0;i<mCount;i++){
|
|
if (mObjects[i]!=NULL){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
if (currentAction->getActivity() > 0){
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
bool ActionLayer::CheckUserInput(u32 key){
|
|
GameObserver * g = GameObserver::GetInstance();
|
|
if (g->waitForExtraPayment && key == PSP_CTRL_CROSS){
|
|
g->waitForExtraPayment = 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;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void ActionLayer::Render (){
|
|
if (menuObject){
|
|
abilitiesMenu->Render();
|
|
return;
|
|
}
|
|
for (int i=0;i<mCount;i++){
|
|
if (mObjects[i]!=NULL){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
//if (currentAction->getActivity() > 0){
|
|
currentAction->Render();
|
|
//return;
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
TargetChooser * ActionLayer::getCurrentTargetChooser(){
|
|
for (int i=0;i<mCount;i++){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
if(currentAction->waitingForAnswer) return currentAction->tc;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int ActionLayer::cancelCurrentAction(){
|
|
ActionElement * ae = isWaitingForAnswer();
|
|
if (!ae) return 0;
|
|
ae->waitingForAnswer = 0; //TODO MOVE THIS IS ActionElement
|
|
return 1;
|
|
}
|
|
|
|
ActionElement * ActionLayer::isWaitingForAnswer(){
|
|
for (int i=0;i<mCount;i++){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
if(currentAction->waitingForAnswer) return currentAction;
|
|
}
|
|
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;
|
|
|
|
for (int i=0;i<mCount;i++){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
if(currentAction->waitingForAnswer){
|
|
return reactToTargetClick(currentAction,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;
|
|
|
|
for (int i=0;i<mCount;i++){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
if(currentAction->waitingForAnswer){
|
|
return reactToClick(currentAction,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){
|
|
menuObject = object;
|
|
|
|
SAFE_DELETE(abilitiesMenu);
|
|
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT);
|
|
abilitiesMenu = NEW SimpleMenu(10, this, mFont, 100, 100);
|
|
|
|
for (int i=0;i<mCount;i++){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
|
if (currentAction->isReactingToTargetClick(object)){
|
|
abilitiesMenu->Add(i,currentAction->getMenuText());
|
|
}
|
|
}
|
|
abilitiesMenu->Add(-1, "Cancel");
|
|
modal = 1;
|
|
}
|
|
|
|
void ActionLayer::doReactTo(int menuIndex){
|
|
|
|
if (menuObject){
|
|
int controlid = abilitiesMenu->mObjects[menuIndex]->GetId();
|
|
char buf[4096];
|
|
sprintf(buf, "ACTIONLAYER doReact To %i\n",controlid);
|
|
OutputDebugString(buf);
|
|
if (controlid != -1){
|
|
ActionElement * currentAction = (ActionElement *)mObjects[controlid];
|
|
currentAction->reactToTargetClick(menuObject);
|
|
}
|
|
menuObject = 0;
|
|
}
|
|
}
|
|
|
|
void ActionLayer::ButtonPressed(int controllerid, int controlid){
|
|
if (controlid == -1){
|
|
}else{
|
|
ActionElement * currentAction = (ActionElement *)mObjects[controlid];
|
|
currentAction->reactToTargetClick(menuObject);
|
|
}
|
|
menuObject = 0;
|
|
|
|
}
|
|
|
|
ActionLayer::~ActionLayer(){
|
|
SAFE_DELETE(abilitiesMenu);
|
|
cleanGarbage();
|
|
}
|