This one was a bit of a doozy to fix correctly, but the actual fix ended up being fairly simple - the upshot is that TargetAbility never checked for whether an extra cost needed setting prior doing a target selection. While at it, I discovered and fixed another bug: if you're in the middle of an extra cost choice (like sacrifice, for instance) and hit the next phase button, the game would let you proceed, and then hang in an endless loop. While at it, did a little cleanup/refactoring around GameObserver's waitForExtraPayment - any time a bool has something that sounds like a verb, it probably deserves to be a function. Now it is. (I needed to refactor it anyway, as I reused that code for the next phase hang.) Note that after this fix, I had to patch two test cases (siege_gang_commander.txt & seismic_assault.txt) - since I've change the selection order (ie a target ability with a sacrifice cost requires the cost to be paid up front before picking the target), this means that tests involving targeting & sacrifices need to switch the order of the cards to pass.
91 lines
2.2 KiB
C++
91 lines
2.2 KiB
C++
#ifndef _GAMEOBSERVER_H_
|
|
#define _GAMEOBSERVER_H_
|
|
|
|
#include "Player.h"
|
|
#include "MTGAbility.h"
|
|
#include "DuelLayers.h"
|
|
#include "MTGCardInstance.h"
|
|
#include "PlayGuiObject.h"
|
|
#include "TargetChooser.h"
|
|
#include "PhaseRing.h"
|
|
#include "ReplacementEffects.h"
|
|
#include "GuiStatic.h"
|
|
#include <queue>
|
|
#include <time.h>
|
|
|
|
class MTGGamePhase;
|
|
class MTGAbility;
|
|
class MTGCardInstance;
|
|
struct CardGui;
|
|
class Player;
|
|
class TargetChooser;
|
|
class Rules;
|
|
using namespace std;
|
|
|
|
class GameObserver{
|
|
protected:
|
|
static GameObserver * mInstance;
|
|
MTGCardInstance * cardWaitingForTargets;
|
|
queue<WEvent *> eventsQueue;
|
|
|
|
int nbPlayers;
|
|
int untap(MTGCardInstance * card);
|
|
bool WaitForExtraPayment(MTGCardInstance* card);
|
|
|
|
public:
|
|
int currentPlayerId;
|
|
CombatStep combatStep;
|
|
int turn;
|
|
int forceShuffleLibraries();
|
|
int targetListIsSet(MTGCardInstance * card);
|
|
PhaseRing * phaseRing;
|
|
int cancelCurrentAction();
|
|
int currentGamePhase;
|
|
ExtraCosts * mExtraPayment;
|
|
int oldGamePhase;
|
|
TargetChooser * targetChooser;
|
|
DuelLayers * mLayers;
|
|
ReplacementEffects *replacementEffects;
|
|
Player * gameOver;
|
|
Player * players[2]; //created outside
|
|
time_t startedAt;
|
|
Rules * mRules;
|
|
|
|
TargetChooser * getCurrentTargetChooser();
|
|
void stackObjectClicked(Interruptible * action);
|
|
|
|
int cardClick(MTGCardInstance * card,Targetable * _object = NULL );
|
|
int getCurrentGamePhase();
|
|
void nextCombatStep();
|
|
void userRequestNextGamePhase();
|
|
void nextGamePhase();
|
|
void cleanupPhase();
|
|
void nextPlayer();
|
|
static void Init(Player * _players[], int _nbplayers);
|
|
static GameObserver * GetInstance();
|
|
static void EndInstance();
|
|
Player * currentPlayer;
|
|
Player * currentActionPlayer;
|
|
Player * isInterrupting;
|
|
Player * opponent();
|
|
Player * currentlyActing();
|
|
GameObserver(Player * _players[], int _nbplayers);
|
|
~GameObserver();
|
|
void stateEffects();
|
|
void eventOccured();
|
|
void addObserver(MTGAbility * observer);
|
|
void removeObserver(ActionElement * observer);
|
|
void startGame(Rules * rules);
|
|
void untapPhase();
|
|
void draw();
|
|
int isInPlay(MTGCardInstance * card);
|
|
|
|
void Update(float dt);
|
|
void Render();
|
|
void ButtonPressed(PlayGuiObject*);
|
|
|
|
int receiveEvent(WEvent * event);
|
|
};
|
|
|
|
#endif
|