Files
wagic/projects/mtg/include/GameObserver.h
zethfoxster 6ee00c138c Pretty huge patch here(sorry old habits never die :( )
lots of changes, many bug fixes,
first
added auto=count(targetchooser)
and countedamount wparsed int
they work together for cards where it is difficult to get working without knowing in advance how many we had ie: exile blah creatures, for each creature you exiled do effect.
auto=count(creature|mybattlefield)
auto=moveto(exile)
auto=draw:countedamount
it takes into account token creatures, which our old methods did not.

second, added "freeze" which is a "frozen" that automatically taps your target for you, for use when nesting or whenever needed where it was difficult to nest the ability with tap included.

added devotion for "iroas"

added reveal:x and scry x
reveal contains optionone/optiononeend ; optiontwo/optiontwoend ; repeat; afterrevealed/afterrevealed end.

this ability has heavy use of targetListIsSet(<amount>) and upto:amount, you MUST be certain that all cards being revealed have an action that removes them from reveal either in the first, second, or 3rd ability.
there are over 300 examples in the new card code, the ability is VERY easy to understand.

scry contains automatic put on top, put on bottom, then scrycore/scrycoreend which is an ability to fire.
it also contains keywords, dontshow which is nested in scrycore, scry reveals, puts on top or bottom, then reveal AGAIN, and does an effect, dontshow eliminates the 2nd revealing.
is also contains "delayed" keyword, which delays the ability until AFTER the core fires.

added bestow. update rules mtg.txt!!!!
examples are in primitives, every bestow card was supported.

added a new lord based on varibles and restrictions
while(restriction{morbid})
while(varible:blah)
this simplifies and expands on this(, allowing you to even use while(cantarget together and check if a card is targetable by the variable. examples are in primitives

added token(by card name)
auto=token(Eldrazi Scion) 
will search primitives and card dats for this card and give it to you as a token.
valid card dat info is still required.

added variable delirium
added restriction madnessplayed to allow checking if the card was played with madness.

added restriction "geared" for checking if a card has equipment on it.

added abilities words
skulk

menace <--cant be blocked except by 2 or more, if you dont block it with 2 or more we automatically unassign the single blocker and the creature is considered not blocked.

nosolo <--cant attack alone

mustblock <---if you dont assign as a blocker, we assign automatically the first thing it can block legally.

changed iscolorless back to "colorless"

enjoy, cards coming soon, theyre coded but im debating on not alpha sorting, cards being added this patch 965 uniques.

there is a section of the commit which was just VS2016 normalizing line ends, sorry if it makes it a cluster mess.
2016-06-28 18:40:55 -04:00

216 lines
6.8 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>
#ifdef NETWORK_SUPPORT
#include "JNetwork.h"
#endif //NETWORK_SUPPORT
class MTGGamePhase;
class MTGAbility;
class MTGCardInstance;
struct CardGui;
class Player;
class TargetChooser;
class Rules;
class TestSuiteGame;
class Trash;
class DeckManager;
using namespace std;
class GameObserver{
protected:
unsigned int mSeed;
GameType mGameType;
MTGCardInstance * cardWaitingForTargets;
queue<WEvent *> eventsQueue;
// used when we're running to log actions
list<string> actionsList;
// used when we're loading to know what to load
list<string> loadingList;
list<string>::iterator loadingite;
RandomGenerator randomGenerator;
WResourceManager* mResourceManager;
JGE* mJGE;
DeckManager* mDeckManager;
Player * gameOver;
GamePhase mCurrentGamePhase;
int untap(MTGCardInstance * card);
bool WaitForExtraPayment(MTGCardInstance* card);
void cleanup();
string startupGameSerialized;
bool parseLine(const string& s);
virtual void logAction(const string& s);
bool processAction(const string& s);
bool processActions(bool undo
#ifdef TESTSUITE
, TestSuiteGame* testgame
#endif
);
friend ostream& operator<<(ostream&, const GameObserver&);
bool mLoading;
void nextGamePhase();
void shuffleLibrary(Player* p);
Player* createPlayer(const string& playerMode
#ifdef TESTSUITE
, TestSuiteGame* testgame
#endif //TESTSUITE
);
public:
int currentPlayerId;
CombatStep combatStep;
int turn;
int forceShuffleLibraries();
int targetListIsSet(MTGCardInstance * card);
PhaseRing * phaseRing;
vector<list<Phase*> >gameTurn;
int cancelCurrentAction();
ExtraCosts * mExtraPayment;
int oldGamePhase;
TargetChooser * targetChooser;
CardDisplay * OpenedDisplay;
DuelLayers * mLayers;
ReplacementEffects *replacementEffects;
vector<Player *> players; //created outside
time_t startedAt;
Rules * mRules;
MTGCardInstance* ExtraRules;
Trash* mTrash;
GameType gameType() const { return mGameType; };
TargetChooser * getCurrentTargetChooser();
void stackObjectClicked(Interruptible * action);
int cardClickLog(bool log, Player* clickedPlayer, MTGGameZone* zone, MTGCardInstance*backup, size_t index, int toReturn);
int cardClick(MTGCardInstance * card, MTGAbility *ability);
int cardClick(MTGCardInstance * card, int abilityType);
int cardClick(MTGCardInstance * card,Targetable * _object = NULL, bool log = true);
GamePhase getCurrentGamePhase();
void setCurrentGamePhase(GamePhase phase) { mCurrentGamePhase = phase; };
const string& getCurrentGamePhaseName();
const string& getNextGamePhaseName();
void nextCombatStep();
void userRequestNextGamePhase(bool allowInterrupt = true, bool log = true);
void cleanupPhase();
void nextPlayer();
#ifdef TESTSUITE
void loadTestSuitePlayer(int playerId, TestSuiteGame* testSuite);
#endif //TESTSUITE
void loadPlayer(int playerId, PlayerType playerType = PLAYER_TYPE_HUMAN, int decknb=0, bool premadeDeck=false);
virtual void loadPlayer(int playerId, Player* player);
Player * currentPlayer;
Player * currentActionPlayer;
Player * isInterrupting;
Player * opponent();
Player * nextTurnsPlayer();
Player * currentlyActing();
GameObserver(WResourceManager* output = 0, JGE* input = 0);
virtual ~GameObserver();
void gameStateBasedEffects();
void enchantmentStatus();
void Affinity();
void addObserver(MTGAbility * observer);
bool removeObserver(ActionElement * observer);
void startGame(GameType, Rules * rules);
void untapPhase();
MTGCardInstance * isCardWaiting(){ return cardWaitingForTargets; }
int isInPlay(MTGCardInstance * card);
int isInGrave(MTGCardInstance * card);
int isInExile(MTGCardInstance * card);
virtual void Update(float dt);
void Render();
void ButtonPressed(PlayGuiObject*);
int getPlayersNumber() {return players.size();};
int receiveEvent(WEvent * event);
bool connectRule;
void logAction(Player* player, const string& s="");
void logAction(int playerId, const string& s="") {
logAction(players[playerId], s);
};
void logAction(MTGCardInstance* card, MTGGameZone* zone, size_t index, int result);
bool load(const string& s, bool undo = false, int controlledPlayerIndex = 0
#ifdef TESTSUITE
, TestSuiteGame* testgame = 0
#endif
);
bool undo();
bool isLoading(){ return mLoading; };
void Mulligan(Player* player = NULL);
void serumMulligan(Player* player = NULL);
Player* getPlayer(size_t index) { return players[index];};
bool isStarted() { return (mLayers!=NULL);};
RandomGenerator* getRandomGenerator() { return &randomGenerator; };
WResourceManager* getResourceManager() { if(this) return mResourceManager;else return 0;};
CardSelectorBase* getCardSelector() { return mLayers->getCardSelector();};
bool operator==(const GameObserver& aGame);
JGE* getInput(){return mJGE;};
DeckManager* getDeckManager(){ return mDeckManager; };
void dumpAssert(bool val);
void resetStartupGame();
void setLoser(Player* aPlayer) {
gameOver = aPlayer;
};
bool didWin(Player* aPlayer = 0) const {
if(!gameOver) {
// nobody won
return false;
} else if(!aPlayer) {
// somebody won and we don't care who
return true;
} else if(gameOver == aPlayer) {
// aPlayer lost
return false;
} else {
// aPlayer won
return true;
}
};
DuelLayers *getView() { return mLayers; };
};
#ifdef NETWORK_SUPPORT
class NetworkGameObserver : public GameObserver
{
protected:
JNetwork* mpNetworkSession;
bool mSynchronized;
bool mForwardAction;
virtual void logAction(const string& s);
public:
// no serverIp means a server is being instantiated, otherwise a client
NetworkGameObserver(JNetwork* pNetwork, WResourceManager* output = 0, JGE* input = 0);
virtual ~NetworkGameObserver();
virtual void loadPlayer(int playerId, Player* player);
virtual void Update(float dt);
void synchronize();
static void loadPlayer(void*pThis, stringstream& in, stringstream& out);
static void sendAction(void*pThis, stringstream& in, stringstream& out);
static void synchronize(void*pThis, stringstream& in, stringstream& out);
static void checkSynchro(void*pxThis, stringstream& in, stringstream& out);
static void ignoreResponse(void*, stringstream&, stringstream&){};
static void disconnect(void*pxThis, stringstream& in, stringstream& out);
};
#endif
#endif