Erwan
- Adding external rules mechanism. It is very crude for the moment, but I hope it will grow. Have a look at Rules/mtg.txt for basic usage
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardSelector.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/SimplePad.o objs/Token.o objs/Translate.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o
|
||||
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardSelector.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/Token.o objs/Translate.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o
|
||||
DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
|
||||
|
||||
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)
|
||||
|
||||
5
projects/mtg/bin/Res/Rules/momir.txt
Normal file
5
projects/mtg/bin/Res/Rules/momir.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
include mtg.txt
|
||||
[INIT]
|
||||
mode=momir
|
||||
[PLAYERS]
|
||||
life:24
|
||||
7
projects/mtg/bin/Res/Rules/mtg.txt
Normal file
7
projects/mtg/bin/Res/Rules/mtg.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
[INIT]
|
||||
mode=mtg
|
||||
[PLAYERS]
|
||||
life:20
|
||||
auto=shuffle
|
||||
auto=draw:7
|
||||
auto=@each my draw:draw:1
|
||||
3
projects/mtg/bin/Res/Rules/random1.txt
Normal file
3
projects/mtg/bin/Res/Rules/random1.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
include mtg.txt
|
||||
[INIT]
|
||||
mode=random1
|
||||
3
projects/mtg/bin/Res/Rules/random2.txt
Normal file
3
projects/mtg/bin/Res/Rules/random2.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
include mtg.txt
|
||||
[INIT]
|
||||
mode=random2
|
||||
6
projects/mtg/bin/Res/Rules/testsuite.txt
Normal file
6
projects/mtg/bin/Res/Rules/testsuite.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
#make sure this file always looks like mtg.txt, minus the initial shuffle and draw
|
||||
[INIT]
|
||||
mode=mtg
|
||||
[PLAYERS]
|
||||
life:20
|
||||
auto=@each my draw:draw:1
|
||||
@@ -62,7 +62,7 @@ class GameApp: public JApp
|
||||
GameState* mGameStates[MAX_STATE];
|
||||
|
||||
public:
|
||||
int players[2];
|
||||
|
||||
|
||||
int gameType;
|
||||
CardEffect *effect;
|
||||
@@ -85,6 +85,7 @@ class GameApp: public JApp
|
||||
static string systemError;
|
||||
static JMusic* music;
|
||||
static MTGAllCards * collection;
|
||||
static int players[2];
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class MTGCardInstance;
|
||||
struct CardGui;
|
||||
class Player;
|
||||
class TargetChooser;
|
||||
class Rules;
|
||||
using namespace std;
|
||||
|
||||
class GameObserver{
|
||||
@@ -70,7 +71,7 @@ class GameObserver{
|
||||
void eventOccured();
|
||||
void addObserver(MTGAbility * observer);
|
||||
void removeObserver(ActionElement * observer);
|
||||
void startGame(int shuffle = 1, int draw = 1);
|
||||
void startGame(Rules * rules);
|
||||
void untapPhase();
|
||||
void draw();
|
||||
int isInPlay(MTGCardInstance * card);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
class TestSuite;
|
||||
#endif
|
||||
class Credits;
|
||||
class Rules;
|
||||
|
||||
|
||||
class GameStateDuel: public GameState, public JGuiListener
|
||||
@@ -33,11 +34,11 @@ class GameStateDuel: public GameState, public JGuiListener
|
||||
bool premadeDeck;
|
||||
int OpponentsDeckid;
|
||||
string musictrack;
|
||||
Rules * rules;
|
||||
|
||||
bool MusicExist(string FileName);
|
||||
void loadPlayer(int playerId, int decknb = 0, int isAI = 0);
|
||||
void loadPlayerMomir(int playerId, int isAI);
|
||||
void loadPlayerRandom(int playerId, int isAI, int mode);
|
||||
|
||||
|
||||
public:
|
||||
GameStateDuel(GameApp* parent);
|
||||
|
||||
@@ -140,6 +140,8 @@ class MTGCardInstance: public MTGCard, public Damageable {
|
||||
static MTGCardInstance AnyCard;
|
||||
static MTGCardInstance NoCard;
|
||||
|
||||
static MTGCardInstance ExtraRules[2];
|
||||
|
||||
};
|
||||
|
||||
ostream& operator<<(ostream&, const MTGCardInstance&);
|
||||
|
||||
@@ -149,16 +149,16 @@ class MTGPlayerCards {
|
||||
MTGGameZone * garbage;
|
||||
MTGGameZone * temp;
|
||||
|
||||
MTGAllCards * collection;
|
||||
|
||||
MTGPlayerCards(MTGAllCards * _collection, int * idList, int idListSize);
|
||||
MTGPlayerCards(MTGAllCards * _collection, MTGDeck * deck);
|
||||
MTGPlayerCards(int * idList, int idListSize);
|
||||
MTGPlayerCards(MTGDeck * deck);
|
||||
~MTGPlayerCards();
|
||||
void initGame(int shuffle = 1, int draw = 1);
|
||||
void setOwner(Player * player);
|
||||
void discardRandom(MTGGameZone * from);
|
||||
void drawFromLibrary();
|
||||
void showHand();
|
||||
void resetLibrary();
|
||||
void initDeck(MTGDeck * deck);
|
||||
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
|
||||
MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
||||
int isInPlay(MTGCardInstance * card);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#define _PHASERING_H_
|
||||
|
||||
#include <list>
|
||||
using std::list;
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
The class that handles the phases of a turn
|
||||
@@ -33,6 +34,7 @@ private:
|
||||
int addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences = 1);
|
||||
int removePhase (int id, Player * player, int allOccurences = 1);
|
||||
static const char * phaseName(int id);
|
||||
static int phaseStrToInt(string s);
|
||||
|
||||
};
|
||||
|
||||
|
||||
74
projects/mtg/include/Rules.h
Normal file
74
projects/mtg/include/Rules.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef _RULES_H_
|
||||
#define _RULES_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
class ManaCost;
|
||||
class Player;
|
||||
class MTGPlayerCards;
|
||||
class MTGDeck;
|
||||
class MTGCardInstance;
|
||||
|
||||
#define MAX_RULES_CARDS 4096;
|
||||
|
||||
class RulesPlayerZone{
|
||||
public:
|
||||
vector<int> cards;
|
||||
void add(int cardid);
|
||||
RulesPlayerZone();
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
class RulesPlayerData{
|
||||
public:
|
||||
vector <string> extraRules;
|
||||
int life;
|
||||
ManaCost * manapool;
|
||||
RulesPlayerZone zones[5];
|
||||
RulesPlayerData();
|
||||
~RulesPlayerData();
|
||||
void cleanup();
|
||||
|
||||
};
|
||||
|
||||
class RulesState{
|
||||
public:
|
||||
int phase;
|
||||
void parsePlayerState(int playerId, string s);
|
||||
RulesState();
|
||||
RulesPlayerData playerData[2];
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
|
||||
class Rules{
|
||||
protected:
|
||||
Player * loadPlayerMomir(int isAI);
|
||||
Player * loadPlayerRandom(int isAI, int mode);
|
||||
Player * initPlayer(int playerId);
|
||||
MTGDeck * buildDeck( int playerId);
|
||||
int strToGameMode(string s);
|
||||
public:
|
||||
enum {
|
||||
PARSE_UNDEFINED,
|
||||
PARSE_INIT,
|
||||
PARSE_PLAYER1,
|
||||
PARSE_PLAYER2,
|
||||
PARSE_PLAYERS
|
||||
};
|
||||
Rules(string filename);
|
||||
int load(string filename);
|
||||
int gamemode;
|
||||
void initPlayers();
|
||||
void addExtraRules();
|
||||
void initGame();
|
||||
void cleanup();
|
||||
vector <string> extraRules;
|
||||
RulesState initState;
|
||||
static int getMTGId(string name);
|
||||
static MTGCardInstance * getCardByMTGId(int mtgid);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -41,7 +41,7 @@ class TestSuite;
|
||||
class TestSuiteState{
|
||||
public:
|
||||
int phase;
|
||||
void parsePlayerState(int playerId, string s,TestSuite * suite);
|
||||
void parsePlayerState(int playerId, string s);
|
||||
TestSuiteState();
|
||||
TestSuitePlayerData playerData[2];
|
||||
void cleanup();
|
||||
@@ -70,13 +70,10 @@ class TestSuite{
|
||||
int assertGame();
|
||||
MTGPlayerCards * buildDeck(int playerId);
|
||||
string getNextAction();
|
||||
int phaseStrToInt(string s);
|
||||
MTGCardInstance * getCardByMTGId(int mtgid);
|
||||
Interruptible * getActionByMTGId(int mtgid);
|
||||
int loadNext();
|
||||
void cleanup();
|
||||
int Log(const char * text);
|
||||
int getMTGId(string name);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -594,7 +594,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, Player * op
|
||||
}
|
||||
|
||||
MTGDeck * tempDeck = NEW MTGDeck(deckFile, collection);
|
||||
MTGPlayerCards * deck = NEW MTGPlayerCards(collection,tempDeck);
|
||||
MTGPlayerCards * deck = NEW MTGPlayerCards(tempDeck);
|
||||
delete tempDeck;
|
||||
AIPlayerBaka * baka = NEW AIPlayerBaka(deck,deckFile, deckFileSmall, avatarFile);
|
||||
return baka;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
hgeParticleSystem* GameApp::Particles[] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
||||
MTGAllCards * GameApp::collection = NULL;
|
||||
int GameApp::players[] = {0,0};
|
||||
int GameApp::HasMusic = 1;
|
||||
JMusic * GameApp::music = NULL;
|
||||
string GameApp::systemError = "";
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../include/ConstraintResolver.h"
|
||||
#include "../include/CardGui.h"
|
||||
#include "../include/Damage.h"
|
||||
#include "../include/Rules.h"
|
||||
#include "../include/ExtraCost.h"
|
||||
|
||||
#include <JRenderer.h>
|
||||
@@ -25,19 +26,15 @@ void GameObserver::EndInstance()
|
||||
|
||||
void GameObserver::Init(Player * _players[], int _nbplayers){
|
||||
mInstance = NEW GameObserver(_players, _nbplayers);
|
||||
mInstance->mLayers = NEW DuelLayers();
|
||||
mInstance->mLayers->init();
|
||||
}
|
||||
|
||||
|
||||
GameObserver::GameObserver(Player * _players[], int _nb_players){
|
||||
int i;
|
||||
|
||||
for (i =0; i < _nb_players;i ++){
|
||||
for (int i = 0; i < _nb_players;i ++){
|
||||
players[i] = _players[i];
|
||||
}
|
||||
currentPlayer = players[0];
|
||||
currentActionPlayer = currentPlayer;
|
||||
currentPlayer = NULL;
|
||||
currentActionPlayer = NULL;
|
||||
isInterrupting = NULL;
|
||||
currentPlayerId = 0;
|
||||
nbPlayers = _nb_players;
|
||||
@@ -47,7 +44,7 @@ GameObserver::GameObserver(Player * _players[], int _nb_players){
|
||||
waitForExtraPayment = NULL;
|
||||
reaction = 0;
|
||||
gameOver = NULL;
|
||||
phaseRing = NEW PhaseRing(_players,_nb_players);
|
||||
phaseRing = NULL;
|
||||
replacementEffects = NEW ReplacementEffects();
|
||||
combatStep = BLOCKERS;
|
||||
}
|
||||
@@ -130,7 +127,7 @@ void GameObserver::nextGamePhase(){
|
||||
untapPhase();
|
||||
break;
|
||||
case Constants::MTG_PHASE_DRAW:
|
||||
mLayers->stackLayer()->addDraw(currentPlayer,1);
|
||||
//mLayers->stackLayer()->addDraw(currentPlayer,1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -190,21 +187,27 @@ int GameObserver::forceShuffleLibraries(){
|
||||
return result;
|
||||
}
|
||||
|
||||
void GameObserver::startGame(int shuffle, int draw){
|
||||
int i;
|
||||
for (i=0; i<nbPlayers; i++)
|
||||
players[i]->game->initGame(shuffle, draw);
|
||||
void GameObserver::startGame(Rules * rules){
|
||||
turn = 0;
|
||||
if (rules)
|
||||
rules->initPlayers();
|
||||
|
||||
mLayers = NEW DuelLayers();
|
||||
mLayers->init();
|
||||
|
||||
currentPlayer = players[0];
|
||||
currentActionPlayer = currentPlayer;
|
||||
phaseRing = NEW PhaseRing(players,nbPlayers);
|
||||
if (rules)
|
||||
rules->initGame();
|
||||
|
||||
//Preload images from hand
|
||||
if (!players[0]->isAI()){
|
||||
for (i=0; i< players[0]->game->hand->nb_cards; i++){
|
||||
for (int i=0; i< players[0]->game->hand->nb_cards; i++){
|
||||
resources.RetrieveCard(players[0]->game->hand->cards[i],CACHE_THUMB);
|
||||
resources.RetrieveCard(players[0]->game->hand->cards[i]);
|
||||
}
|
||||
}
|
||||
turn = 0;
|
||||
phaseRing->goToPhase(Constants::MTG_PHASE_FIRSTMAIN, players[0]);
|
||||
currentGamePhase = Constants::MTG_PHASE_FIRSTMAIN;
|
||||
|
||||
//Difficult mode special stuff
|
||||
if (!players[0]->isAI() && players[1]->isAI()){
|
||||
@@ -250,6 +253,10 @@ GameObserver::~GameObserver(){
|
||||
SAFE_DELETE(mLayers);
|
||||
SAFE_DELETE(phaseRing);
|
||||
SAFE_DELETE(replacementEffects);
|
||||
for (int i = 0; i < nbPlayers; ++i){
|
||||
SAFE_DELETE(players[i]->game);
|
||||
SAFE_DELETE(players[i]);
|
||||
}
|
||||
LOG("==GameObserver Destroyed==");
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "../include/MTGRules.h"
|
||||
#include "../include/Credits.h"
|
||||
#include "../include/Translate.h"
|
||||
#include "../include/Rules.h"
|
||||
|
||||
#ifdef TESTSUITE
|
||||
#include "../include/TestSuiteAI.h"
|
||||
@@ -57,6 +58,7 @@ GameStateDuel::GameStateDuel(GameApp* parent): GameState(parent) {
|
||||
#endif
|
||||
|
||||
credits = NULL;
|
||||
rules = NULL;
|
||||
}
|
||||
|
||||
GameStateDuel::~GameStateDuel() {
|
||||
@@ -100,62 +102,13 @@ void GameStateDuel::Start()
|
||||
premadeDeck = true;
|
||||
fillDeckMenu(deckmenu,RESPATH"/player/premade");
|
||||
}
|
||||
//mGamePhase = DUEL_STATE_ERROR_NO_DECK;
|
||||
|
||||
for (int i = 0; i < 2; ++i){
|
||||
mPlayers[i] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GameStateDuel::loadPlayerRandom(int playerId, int isAI, int mode){
|
||||
int color1 = 1 + WRand() % 5;
|
||||
int color2 = 1 + WRand() % 5;
|
||||
int color0 = Constants::MTG_COLOR_ARTIFACT;
|
||||
if (mode == GAME_TYPE_RANDOM1) color2 = color1;
|
||||
int colors[]={color1,color2,color0};
|
||||
int nbcolors = 3;
|
||||
|
||||
string lands[] = {"forest", "forest", "island", "mountain", "swamp", "plains", "forest"};
|
||||
|
||||
|
||||
MTGDeck * tempDeck = NEW MTGDeck(mParent->collection);
|
||||
tempDeck->addRandomCards(9,0,0,-1,lands[color1].c_str());
|
||||
tempDeck->addRandomCards(9,0,0,-1,lands[color2].c_str());
|
||||
tempDeck->addRandomCards(1,0,0,'U',"land");
|
||||
tempDeck->addRandomCards(1,0,0,'R',"land");
|
||||
tempDeck->addRandomCards(12,0,0,-1,"creature",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"sorcery",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"enchantment",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"instant",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"artifact",colors,nbcolors);
|
||||
|
||||
string deckFile = "random";
|
||||
string deckFileSmall = "random";
|
||||
|
||||
deck[playerId] = NEW MTGPlayerCards(mParent->collection, tempDeck);
|
||||
if (!isAI) // Human Player
|
||||
mPlayers[playerId] = NEW HumanPlayer(deck[playerId], deckFile, deckFileSmall);
|
||||
else
|
||||
mPlayers[playerId] = NEW AIPlayerBaka(deck[playerId],deckFile, deckFileSmall, "");
|
||||
delete tempDeck;
|
||||
}
|
||||
|
||||
|
||||
void GameStateDuel::loadPlayerMomir(int playerId, int isAI){
|
||||
string deckFileSmall = "momir";
|
||||
char empty[] = "";
|
||||
MTGDeck * tempDeck = NEW MTGDeck(mParent->collection); //Autogenerate a momir deck. Leave the "momir.txt" bits below for stats.
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Forest");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Plains");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Swamp");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Mountain");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Island");
|
||||
|
||||
deck[playerId] = NEW MTGPlayerCards(mParent->collection, tempDeck);
|
||||
if (!isAI) // Human Player
|
||||
mPlayers[playerId] = NEW HumanPlayer(deck[playerId], options.profileFile("momir.txt","",true).c_str(), deckFileSmall);
|
||||
else
|
||||
mPlayers[playerId] = NEW AIMomirPlayer(deck[playerId], options.profileFile("momir.txt","",true).c_str(), deckFileSmall, empty);
|
||||
delete tempDeck;
|
||||
}
|
||||
|
||||
void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){
|
||||
if (decknb){
|
||||
if (!isAI){ //Human Player
|
||||
@@ -167,7 +120,7 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){
|
||||
char deckFileSmall[255];
|
||||
sprintf(deckFileSmall, "player_deck%i",decknb);
|
||||
MTGDeck * tempDeck = NEW MTGDeck(deckFile, mParent->collection);
|
||||
deck[playerId] = NEW MTGPlayerCards(mParent->collection,tempDeck);
|
||||
deck[playerId] = NEW MTGPlayerCards(tempDeck);
|
||||
delete tempDeck;
|
||||
mPlayers[playerId] = NEW HumanPlayer(deck[playerId],deckFile, deckFileSmall);
|
||||
}else{ //AI Player, chose deck
|
||||
@@ -195,22 +148,18 @@ void GameStateDuel::initRand(unsigned int seed){
|
||||
void GameStateDuel::loadTestSuitePlayers(){
|
||||
if (!testSuite) return;
|
||||
initRand(testSuite->seed);
|
||||
SAFE_DELETE(game);
|
||||
for (int i = 0; i < 2; i++){
|
||||
SAFE_DELETE(mPlayers[i]);
|
||||
SAFE_DELETE(deck[i]);
|
||||
mPlayers[i] = NEW TestSuiteAI(testSuite, i);
|
||||
deck[i] = mPlayers[i]->game;
|
||||
}
|
||||
mParent->gameType = testSuite->gameType;
|
||||
SAFE_DELETE(game);
|
||||
|
||||
GameObserver::Init(mPlayers, 2);
|
||||
game = GameObserver::GetInstance();
|
||||
game->startGame(0,0);
|
||||
game->startGame(rules);
|
||||
if (mParent->gameType == GAME_TYPE_MOMIR){
|
||||
game->addObserver(NEW MTGMomirRule(-1, mParent->collection));
|
||||
for (int i = 0; i < 2; i++){
|
||||
game->players[i]->life+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -233,11 +182,12 @@ void GameStateDuel::End()
|
||||
premadeDeck = false;
|
||||
|
||||
for (int i = 0; i < 2; i++){
|
||||
SAFE_DELETE(mPlayers[i]);
|
||||
SAFE_DELETE(deck[i]);
|
||||
mPlayers[i] = NULL;
|
||||
deck[i] = NULL;
|
||||
}
|
||||
|
||||
SAFE_DELETE(credits);
|
||||
SAFE_DELETE(rules);
|
||||
|
||||
SAFE_DELETE(menu);
|
||||
SAFE_DELETE(opponentMenu);
|
||||
@@ -270,27 +220,21 @@ void GameStateDuel::Update(float dt)
|
||||
break;
|
||||
case DUEL_STATE_CHOOSE_DECK1:
|
||||
if (mParent->gameType == GAME_TYPE_MOMIR){
|
||||
for (int i = 0; i < 2; i++){
|
||||
int isAI = 1;
|
||||
if (mParent->players[i] == PLAYER_TYPE_HUMAN) isAI = 0;
|
||||
loadPlayerMomir(i, isAI);
|
||||
}
|
||||
rules = NEW Rules("momir.txt");
|
||||
mGamePhase = DUEL_STATE_PLAY;
|
||||
} else if (mParent->gameType == GAME_TYPE_RANDOM1 || mParent->gameType == GAME_TYPE_RANDOM2){
|
||||
for (int i = 0; i < 2; i++){
|
||||
int isAI = 1;
|
||||
if (mParent->players[i] == PLAYER_TYPE_HUMAN) isAI = 0;
|
||||
loadPlayerRandom(i, isAI, mParent->gameType);
|
||||
}
|
||||
} else if (mParent->gameType == GAME_TYPE_RANDOM1){
|
||||
rules = NEW Rules ("random1.txt");
|
||||
mGamePhase = DUEL_STATE_PLAY;
|
||||
}else if (mParent->players[0] == PLAYER_TYPE_HUMAN)
|
||||
deckmenu->Update(dt);
|
||||
}else if (mParent->gameType == GAME_TYPE_RANDOM2) {
|
||||
rules = NEW Rules ("random2.txt");
|
||||
mGamePhase = DUEL_STATE_PLAY;
|
||||
}
|
||||
#ifdef TESTSUITE
|
||||
else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){
|
||||
if (testSuite && testSuite->loadNext()){
|
||||
|
||||
loadTestSuitePlayers();
|
||||
|
||||
rules = NEW Rules("testsuite.txt");
|
||||
mGamePhase = DUEL_STATE_PLAY;
|
||||
testSuite->initGame();
|
||||
char buf[4096];
|
||||
@@ -306,8 +250,13 @@ void GameStateDuel::Update(float dt)
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
loadPlayer(0);
|
||||
mGamePhase = DUEL_STATE_CHOOSE_DECK2;
|
||||
if (!rules) rules = NEW Rules("mtg.txt");
|
||||
if (mParent->players[0] == PLAYER_TYPE_HUMAN)
|
||||
deckmenu->Update(dt);
|
||||
else{
|
||||
loadPlayer(0);
|
||||
mGamePhase = DUEL_STATE_CHOOSE_DECK2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DUEL_STATE_CHOOSE_DECK1_TO_2:
|
||||
@@ -348,12 +297,9 @@ void GameStateDuel::Update(float dt)
|
||||
if (!game){
|
||||
GameObserver::Init(mPlayers, 2);
|
||||
game = GameObserver::GetInstance();
|
||||
game->startGame();
|
||||
game->startGame(rules);
|
||||
if (mParent->gameType == GAME_TYPE_MOMIR){
|
||||
game->addObserver(NEW MTGMomirRule(-1, mParent->collection));
|
||||
for (int i = 0; i < 2; i++){
|
||||
game->players[i]->life+=4;
|
||||
}
|
||||
}
|
||||
//stop menu music
|
||||
if (GameApp::music){
|
||||
@@ -389,7 +335,7 @@ void GameStateDuel::Update(float dt)
|
||||
// mParent->effect->UpdateSmall(dt);
|
||||
game->Update(dt);
|
||||
if (game->gameOver){
|
||||
credits->compute(mPlayers[0],mPlayers[1], mParent);
|
||||
credits->compute(game->players[0],game->players[1], mParent);
|
||||
mGamePhase = DUEL_STATE_END;
|
||||
#ifdef TESTSUITE
|
||||
if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){
|
||||
|
||||
@@ -21,7 +21,7 @@ static int colors[] =
|
||||
};
|
||||
*/
|
||||
|
||||
GuiPhaseBar::GuiPhaseBar() : phase(GameObserver::GetInstance()->phaseRing->getCurrentPhase()), angle(0.0f)
|
||||
GuiPhaseBar::GuiPhaseBar() : phase(NULL), angle(0.0f)
|
||||
{
|
||||
JQuad * quad;
|
||||
if ((quad = resources.GetQuad("phasebar")) != NULL){
|
||||
|
||||
@@ -844,8 +844,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card, int
|
||||
if (!target) target = card;
|
||||
string magicText = card->magicText;
|
||||
if (card->alias && magicText.size() == 0){
|
||||
//An awful way to get access to the aliasedcard
|
||||
MTGCard * c = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias);
|
||||
MTGCard * c = GameApp::collection->getCardById(card->alias);
|
||||
if (!c) return 0;
|
||||
magicText = c->magicText;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ using namespace std;
|
||||
MTGCardInstance MTGCardInstance::AnyCard = MTGCardInstance();
|
||||
MTGCardInstance MTGCardInstance::NoCard = MTGCardInstance();
|
||||
|
||||
MTGCardInstance MTGCardInstance::ExtraRules[] = {MTGCardInstance(), MTGCardInstance()};
|
||||
|
||||
|
||||
|
||||
MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0), view(NULL){
|
||||
LOG("==Creating MTGCardInstance==");
|
||||
initMTGCI();
|
||||
|
||||
@@ -14,12 +14,11 @@
|
||||
//Players Game
|
||||
//------------------------------
|
||||
|
||||
MTGPlayerCards::MTGPlayerCards(MTGAllCards * _collection, int * idList, int idListSize){
|
||||
MTGPlayerCards::MTGPlayerCards(int * idList, int idListSize){
|
||||
init();
|
||||
int i;
|
||||
collection = _collection;
|
||||
for (i=0;i<idListSize;i++){
|
||||
MTGCard * card = collection->getCardById(idList[i]);
|
||||
MTGCard * card = GameApp::collection->getCardById(idList[i]);
|
||||
if (card){
|
||||
MTGCardInstance * newCard = NEW MTGCardInstance(card, this);
|
||||
library->addCard(newCard);
|
||||
@@ -27,9 +26,14 @@ MTGPlayerCards::MTGPlayerCards(MTGAllCards * _collection, int * idList, int idLi
|
||||
}
|
||||
}
|
||||
|
||||
MTGPlayerCards::MTGPlayerCards(MTGAllCards * _collection, MTGDeck * deck){
|
||||
MTGPlayerCards::MTGPlayerCards(MTGDeck * deck){
|
||||
init();
|
||||
collection = _collection;
|
||||
initDeck(deck);
|
||||
}
|
||||
|
||||
|
||||
void MTGPlayerCards::initDeck(MTGDeck * deck){
|
||||
resetLibrary();
|
||||
map<int,int>::iterator it;
|
||||
for (it = deck->cards.begin(); it!=deck->cards.end(); it++){
|
||||
MTGCard * card = deck->getCardById(it->first);
|
||||
@@ -83,6 +87,11 @@ void MTGPlayerCards::drawFromLibrary(){
|
||||
}
|
||||
}
|
||||
|
||||
void MTGPlayerCards::resetLibrary(){
|
||||
SAFE_DELETE(library);
|
||||
library = NEW MTGLibrary();
|
||||
}
|
||||
|
||||
void MTGPlayerCards::init(){
|
||||
library = NEW MTGLibrary();
|
||||
graveyard = NEW MTGGraveyard();
|
||||
|
||||
@@ -5,6 +5,26 @@
|
||||
#include "../include/WEvent.h"
|
||||
|
||||
|
||||
//Parses a string and gives phase numer
|
||||
int PhaseRing::phaseStrToInt(string s){
|
||||
if (s.compare("untap") == 0) return Constants::MTG_PHASE_UNTAP;
|
||||
if (s.compare("upkeep") == 0)return Constants::MTG_PHASE_UPKEEP;
|
||||
if (s.compare("draw") == 0)return Constants::MTG_PHASE_DRAW;
|
||||
if (s.compare("firstmain") == 0)return Constants::MTG_PHASE_FIRSTMAIN;
|
||||
if (s.compare("combatbegin") == 0)return Constants::MTG_PHASE_COMBATBEGIN;
|
||||
if (s.compare("combatattackers") == 0)return Constants::MTG_PHASE_COMBATATTACKERS;
|
||||
if (s.compare("combatblockers") == 0)return Constants::MTG_PHASE_COMBATBLOCKERS;
|
||||
if (s.compare("combatdamage") == 0)return Constants::MTG_PHASE_COMBATDAMAGE;
|
||||
if (s.compare("combatend") == 0)return Constants::MTG_PHASE_COMBATEND;
|
||||
if (s.compare("secondmain") == 0)return Constants::MTG_PHASE_SECONDMAIN;
|
||||
if (s.compare("endofturn") == 0)return Constants::MTG_PHASE_ENDOFTURN;
|
||||
if (s.compare("cleanup") == 0)return Constants::MTG_PHASE_CLEANUP;
|
||||
OutputDebugString("PHASERING: Unknown Phase name:");
|
||||
OutputDebugString(s.c_str());
|
||||
OutputDebugString("\n");
|
||||
return Constants::MTG_PHASE_FIRSTMAIN;
|
||||
}
|
||||
|
||||
/* Creates a New phase ring with the default rules */
|
||||
PhaseRing::PhaseRing(Player* players[], int nbPlayers){
|
||||
for (int i = 0; i < nbPlayers; i++){
|
||||
@@ -24,19 +44,19 @@ PhaseRing::~PhaseRing(){
|
||||
}
|
||||
}
|
||||
|
||||
//Tells if next phase will be another Damage phase rather than combat ends
|
||||
bool PhaseRing::extraDamagePhase(int id){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (id != Constants::MTG_PHASE_COMBATEND) return false;
|
||||
if (g->combatStep != END_FIRST_STRIKE) return false;
|
||||
for (int j = 0; j < 2; ++j){
|
||||
MTGGameZone * z = g->players[j]->game->inPlay;
|
||||
//Tells if next phase will be another Damage phase rather than combat ends
|
||||
bool PhaseRing::extraDamagePhase(int id){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (id != Constants::MTG_PHASE_COMBATEND) return false;
|
||||
if (g->combatStep != END_FIRST_STRIKE) return false;
|
||||
for (int j = 0; j < 2; ++j){
|
||||
MTGGameZone * z = g->players[j]->game->inPlay;
|
||||
for (int i= 0; i < z->nb_cards; ++i){
|
||||
MTGCardInstance * card = z->cards[i];
|
||||
if ((card->isAttacker() || card->isDefenser()) && !(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE))) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * PhaseRing::phaseName(int id){
|
||||
|
||||
390
projects/mtg/src/Rules.cpp
Normal file
390
projects/mtg/src/Rules.cpp
Normal file
@@ -0,0 +1,390 @@
|
||||
#include "../include/Rules.h"
|
||||
#include "../include/mtgdefinitions.h"
|
||||
#include "../include/config.h"
|
||||
#include "../include/Manacost.h"
|
||||
#include "../include/Player.h"
|
||||
#include "../include/AIMomirPlayer.h"
|
||||
|
||||
#include "../include/MTGGameZones.h"
|
||||
#include "../include/MTGAbility.h"
|
||||
|
||||
int Rules::getMTGId(string cardName){
|
||||
int cardnb = atoi(cardName.c_str());
|
||||
if (cardnb) return cardnb;
|
||||
if (cardName.compare("*") == 0) return -1; //Any card
|
||||
MTGCard * card = GameApp::collection->getCardByName(cardName);
|
||||
if (card) return card->getMTGId();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MTGCardInstance * Rules::getCardByMTGId(int mtgid){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = g->players[i];
|
||||
MTGGameZone * zones[] = {p->game->library,p->game->hand, p->game->inPlay, p->game->graveyard};
|
||||
for (int j = 0; j < 4; j++){
|
||||
MTGGameZone * zone = zones[j];
|
||||
for (int k = 0; k < zone->nb_cards; k++){
|
||||
MTGCardInstance * card = zone->cards[k];
|
||||
if (!card) return NULL;
|
||||
if (card->getMTGId() == mtgid) return card;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RulesPlayerData::RulesPlayerData(){
|
||||
life = 20;
|
||||
manapool = NEW ManaCost();
|
||||
}
|
||||
|
||||
RulesPlayerData::~RulesPlayerData(){
|
||||
SAFE_DELETE(manapool);
|
||||
}
|
||||
|
||||
RulesPlayerZone::RulesPlayerZone(){
|
||||
}
|
||||
|
||||
void RulesPlayerZone::add(int cardId){
|
||||
cards.push_back(cardId);
|
||||
}
|
||||
|
||||
RulesState::RulesState(){
|
||||
phase = Constants::MTG_PHASE_FIRSTMAIN;
|
||||
|
||||
}
|
||||
|
||||
void RulesState::parsePlayerState(int playerId, string s){
|
||||
size_t limiter = s.find("=");
|
||||
if (limiter == string::npos) limiter = s.find(":");
|
||||
string areaS;
|
||||
int area;
|
||||
if (limiter != string::npos){
|
||||
areaS = s.substr(0,limiter);
|
||||
if (areaS.compare("graveyard") == 0){
|
||||
area = 0;
|
||||
}else if(areaS.compare("library") == 0){
|
||||
area = 1;
|
||||
}else if(areaS.compare("hand") == 0){
|
||||
area = 2;
|
||||
}else if(areaS.compare("inplay") == 0 || areaS.compare("battlefield") == 0 ){
|
||||
area = 3;
|
||||
}else if(areaS.compare("life") == 0){
|
||||
playerData[playerId].life = atoi((s.substr(limiter+1)).c_str());
|
||||
return;
|
||||
}else if(areaS.compare("manapool") == 0){
|
||||
SAFE_DELETE(playerData[playerId].manapool);
|
||||
playerData[playerId].manapool = ManaCost::parseManaCost(s.substr(limiter+1));
|
||||
return;
|
||||
}else if(areaS.compare("auto") == 0){
|
||||
playerData[playerId].extraRules.push_back(s.substr(limiter+1));
|
||||
return;
|
||||
}else{
|
||||
return; // ERROR
|
||||
}
|
||||
s = s.substr(limiter+1);
|
||||
while (s.size()){
|
||||
unsigned int value;
|
||||
limiter = s.find(",");
|
||||
if (limiter != string::npos){
|
||||
value = Rules::getMTGId(s.substr(0,limiter));
|
||||
s = s.substr(limiter+1);
|
||||
}else{
|
||||
value = Rules::getMTGId(s);
|
||||
s = "";
|
||||
}
|
||||
if (value) playerData[playerId].zones[area].add(value);
|
||||
}
|
||||
}else{
|
||||
//ERROR
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Rules::addExtraRules(){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
|
||||
int id = g->mLayers->actionLayer()->getMaxId();
|
||||
for (int i = 0; i < 2; ++i){
|
||||
Player * p = g->players[i];
|
||||
//Trick so that the abilities don't die;
|
||||
MTGCardInstance::ExtraRules[i].currentZone = p->game->inPlay;
|
||||
MTGCardInstance::ExtraRules[i].lastController = p;
|
||||
for (size_t j = 0; j< initState.playerData[i].extraRules.size(); ++j){
|
||||
AbilityFactory af;
|
||||
MTGAbility * a = af.parseMagicLine(initState.playerData[i].extraRules[j], id++, NULL,&MTGCardInstance::ExtraRules[i]);
|
||||
if (a){
|
||||
if (a->oneShot){
|
||||
a->resolve();
|
||||
delete(a);
|
||||
}else{
|
||||
a->addToGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t j = 0; j< extraRules.size(); ++j){
|
||||
AbilityFactory af;
|
||||
MTGAbility * a = af.parseMagicLine(extraRules[j], id++, NULL,&MTGCardInstance::ExtraRules[0]);
|
||||
if (a){
|
||||
if (a->oneShot){
|
||||
a->resolve();
|
||||
delete(a);
|
||||
}else{
|
||||
a->addToGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Player * Rules::loadPlayerMomir(int isAI){
|
||||
string deckFileSmall = "momir";
|
||||
char empty[] = "";
|
||||
|
||||
MTGDeck * tempDeck = NEW MTGDeck(GameApp::collection); //Autogenerate a momir deck. Leave the "momir.txt" bits below for stats.
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Forest");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Plains");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Swamp");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Mountain");
|
||||
tempDeck->addRandomCards(12, 0,0,Constants::RARITY_L,"Island");
|
||||
|
||||
MTGPlayerCards * deck = NEW MTGPlayerCards( tempDeck);
|
||||
delete tempDeck;
|
||||
if (!isAI) // Human Player
|
||||
return NEW HumanPlayer(deck, options.profileFile("momir.txt","",true).c_str(), deckFileSmall);
|
||||
else
|
||||
return NEW AIMomirPlayer(deck, options.profileFile("momir.txt","",true).c_str(), deckFileSmall, empty);
|
||||
|
||||
}
|
||||
|
||||
Player * Rules::loadPlayerRandom(int isAI, int mode){
|
||||
int color1 = 1 + WRand() % 5;
|
||||
int color2 = 1 + WRand() % 5;
|
||||
int color0 = Constants::MTG_COLOR_ARTIFACT;
|
||||
if (mode == GAME_TYPE_RANDOM1) color2 = color1;
|
||||
int colors[]={color1,color2,color0};
|
||||
int nbcolors = 3;
|
||||
|
||||
string lands[] = {"forest", "forest", "island", "mountain", "swamp", "plains", "forest"};
|
||||
|
||||
|
||||
MTGDeck * tempDeck = NEW MTGDeck(GameApp::collection);
|
||||
tempDeck->addRandomCards(9,0,0,-1,lands[color1].c_str());
|
||||
tempDeck->addRandomCards(9,0,0,-1,lands[color2].c_str());
|
||||
tempDeck->addRandomCards(1,0,0,'U',"land");
|
||||
tempDeck->addRandomCards(1,0,0,'R',"land");
|
||||
tempDeck->addRandomCards(12,0,0,-1,"creature",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"sorcery",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"enchantment",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"instant",colors,nbcolors);
|
||||
tempDeck->addRandomCards(2,0,0,-1,"artifact",colors,nbcolors);
|
||||
|
||||
string deckFile = "random";
|
||||
string deckFileSmall = "random";
|
||||
|
||||
MTGPlayerCards * deck = NEW MTGPlayerCards(tempDeck);
|
||||
delete tempDeck;
|
||||
|
||||
if (!isAI) // Human Player
|
||||
return NEW HumanPlayer(deck, deckFile, deckFileSmall);
|
||||
else
|
||||
return NEW AIPlayerBaka(deck,deckFile, deckFileSmall, "");
|
||||
}
|
||||
|
||||
|
||||
Player * Rules::initPlayer(int playerId){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
Player * p = g->players[playerId];
|
||||
if (!p) {
|
||||
int isAI = 1;
|
||||
if (GameApp::players[playerId] == PLAYER_TYPE_HUMAN) isAI = 0;
|
||||
switch(gamemode){
|
||||
case GAME_TYPE_MOMIR:
|
||||
return loadPlayerMomir(isAI);
|
||||
case GAME_TYPE_CLASSIC:
|
||||
return NULL; //Error for the time being
|
||||
case GAME_TYPE_RANDOM1:
|
||||
return loadPlayerRandom(isAI,GAME_TYPE_RANDOM1);
|
||||
case GAME_TYPE_RANDOM2:
|
||||
return loadPlayerRandom(isAI,GAME_TYPE_RANDOM2);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
MTGDeck * Rules::buildDeck( int playerId){
|
||||
int nbcards = 0;
|
||||
MTGDeck * deck = NEW MTGDeck(GameApp::collection);
|
||||
for (int j = 0; j < 4; j++){
|
||||
for (size_t k = 0; k < initState.playerData[playerId].zones[j].cards.size(); k++){
|
||||
int cardid = initState.playerData[playerId].zones[j].cards[k];
|
||||
deck->add(cardid);
|
||||
nbcards++;
|
||||
}
|
||||
}
|
||||
if (!nbcards){
|
||||
delete(deck);
|
||||
return NULL;
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
|
||||
void Rules::initPlayers(){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = initPlayer(i);
|
||||
g->players[i] = p;
|
||||
MTGDeck * deck = buildDeck(i);
|
||||
if (deck) {
|
||||
p->game->initDeck(deck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rules::initGame(){
|
||||
//Put the GameObserver in the initial state
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
OutputDebugString("RULES Init Game\n");
|
||||
g->phaseRing->goToPhase(initState.phase, g->players[0]);
|
||||
g->currentGamePhase = initState.phase;
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = g->players[i];
|
||||
p->life = initState.playerData[i].life;
|
||||
p->getManaPool()->copy(initState.playerData[i].manapool);
|
||||
MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay};
|
||||
for (int j = 0; j < 4; j++){
|
||||
MTGGameZone * zone = playerZones[j];
|
||||
for (size_t k = 0; k < initState.playerData[i].zones[j].cards.size(); k++){
|
||||
MTGCardInstance * card = getCardByMTGId(initState.playerData[i].zones[j].cards[k]);
|
||||
if (card && zone != p->game->library){
|
||||
if (zone == p->game->inPlay){
|
||||
MTGCardInstance * copy = p->game->putInZone(card, p->game->library, p->game->stack);
|
||||
Spell * spell = NEW Spell(copy);
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
}else{
|
||||
if (!p->game->library->hasCard(card)){
|
||||
LOG ("RULES ERROR, CARD NOT FOUND IN LIBRARY\n");
|
||||
}
|
||||
p->game->putInZone(card,p->game->library,zone);
|
||||
}
|
||||
}else{
|
||||
if (!card) { LOG ("RULES ERROR, card is NULL\n"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
addExtraRules();
|
||||
OutputDebugString("RULES Init Game Done !\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RulesPlayerZone::cleanup(){
|
||||
cards.clear();
|
||||
}
|
||||
|
||||
void RulesPlayerData::cleanup(){
|
||||
if (manapool) delete manapool;
|
||||
manapool = NULL;
|
||||
manapool = NEW ManaCost();
|
||||
for (int i = 0; i < 5; i++){
|
||||
zones[i].cleanup();
|
||||
}
|
||||
life=20;
|
||||
}
|
||||
|
||||
void RulesState::cleanup(){
|
||||
for (int i = 0; i < 2; i++){
|
||||
playerData[i].cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
void Rules::cleanup(){
|
||||
initState.cleanup();
|
||||
}
|
||||
|
||||
Rules::Rules(string filename){
|
||||
load(filename);
|
||||
|
||||
}
|
||||
|
||||
int Rules::load(string _filename){
|
||||
|
||||
char filename[4096];
|
||||
sprintf(filename, RESPATH"/Rules/%s", _filename.c_str());
|
||||
std::ifstream file(filename);
|
||||
std::string s;
|
||||
|
||||
int state = PARSE_UNDEFINED;
|
||||
|
||||
// std::cout << std::endl << std::endl << "!!!" << file << std::endl << std::endl;
|
||||
if (!file) return 0;
|
||||
|
||||
cleanup();
|
||||
while(std::getline(file,s)){
|
||||
if (!s.size()) continue;
|
||||
if (s[s.size()-1] == '\r') s.erase(s.size()-1); //Handle DOS files
|
||||
if (s[0] == '#') continue;
|
||||
std::transform( s.begin(), s.end(), s.begin(),::tolower );
|
||||
if (s.find("include ") == 0) {
|
||||
load (s.substr(8));
|
||||
continue;
|
||||
}
|
||||
if (s.compare("[init]") == 0) {
|
||||
state = PARSE_INIT;
|
||||
continue;
|
||||
}
|
||||
if (s.compare("[players]") == 0) {
|
||||
state = PARSE_PLAYERS;
|
||||
continue;
|
||||
}
|
||||
if (s.compare("[player1]") == 0) {
|
||||
state = PARSE_PLAYER1;
|
||||
continue;
|
||||
}
|
||||
if (s.compare("[player2]") == 0) {
|
||||
state = PARSE_PLAYER2;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(state){
|
||||
case PARSE_UNDEFINED:
|
||||
break;
|
||||
case PARSE_INIT:
|
||||
if (s.find("auto=") == 0){
|
||||
extraRules.push_back(s.substr(5));
|
||||
}else if (s.find("mode=") == 0) {
|
||||
gamemode = strToGameMode(s.substr(5));
|
||||
}else{
|
||||
initState.phase = PhaseRing::phaseStrToInt(s);
|
||||
}
|
||||
break;
|
||||
case PARSE_PLAYER1:
|
||||
initState.parsePlayerState(0, s);
|
||||
break;
|
||||
case PARSE_PLAYER2:
|
||||
initState.parsePlayerState(1, s);
|
||||
break;
|
||||
case PARSE_PLAYERS:
|
||||
initState.parsePlayerState(0, s);
|
||||
initState.parsePlayerState(1, s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Rules::strToGameMode(string s){
|
||||
if (s.compare("momir")==0) return GAME_TYPE_MOMIR;
|
||||
if (s.compare("random1")==0) return GAME_TYPE_RANDOM1;
|
||||
if (s.compare("random2")==0) return GAME_TYPE_RANDOM2;
|
||||
return GAME_TYPE_CLASSIC;
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../include/MTGRules.h"
|
||||
#include "../include/ActionLayer.h"
|
||||
#include "../include/GuiCombat.h"
|
||||
#include "../include/Rules.h"
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
@@ -23,31 +24,6 @@ TestSuiteAI::TestSuiteAI(TestSuite * _suite, int playerId):AIPlayerBaka(_suite->
|
||||
|
||||
}
|
||||
|
||||
int TestSuite::getMTGId(string cardName){
|
||||
int cardnb = atoi(cardName.c_str());
|
||||
if (cardnb) return cardnb;
|
||||
if (cardName.compare("*") == 0) return -1; //Any card
|
||||
MTGCard * card = collection->getCardByName(cardName);
|
||||
if (card) return card->getMTGId();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MTGCardInstance * TestSuite::getCardByMTGId(int mtgid){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = g->players[i];
|
||||
MTGGameZone * zones[] = {p->game->library,p->game->hand, p->game->inPlay, p->game->graveyard};
|
||||
for (int j = 0; j < 4; j++){
|
||||
MTGGameZone * zone = zones[j];
|
||||
for (int k = 0; k < zone->nb_cards; k++){
|
||||
MTGCardInstance * card = zone->cards[k];
|
||||
if (!card) return NULL;
|
||||
if (card->getMTGId() == mtgid) return card;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Interruptible * TestSuite::getActionByMTGId(int mtgid){
|
||||
ActionStack * as= GameObserver::GetInstance()->mLayers->stackLayer();
|
||||
@@ -139,10 +115,10 @@ int TestSuiteAI::Act(float dt){
|
||||
g->mLayers->actionLayer()->doReactTo(choice);
|
||||
}else if(action.find(" -momir- ")!=string::npos){
|
||||
int start = action.find(" -momir- ");
|
||||
int cardId = suite->getMTGId(action.substr(start + 9).c_str());
|
||||
int cardIdHand = suite->getMTGId(action.substr(0,start).c_str());
|
||||
int cardId = Rules::getMTGId(action.substr(start + 9).c_str());
|
||||
int cardIdHand = Rules::getMTGId(action.substr(0,start).c_str());
|
||||
MTGMomirRule * a = ((MTGMomirRule *)g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR));
|
||||
a->reactToClick(suite->getCardByMTGId(cardIdHand), cardId);
|
||||
a->reactToClick(Rules::getCardByMTGId(cardIdHand), cardId);
|
||||
g->mLayers->actionLayer()->stuffHappened = 1;
|
||||
}else if(action.find("p1")!=string::npos || action.find("p2")!=string::npos){
|
||||
Player * p = g->players[1];
|
||||
@@ -150,7 +126,7 @@ int TestSuiteAI::Act(float dt){
|
||||
if (start != string::npos) p = g->players[0];
|
||||
g->cardClick(NULL, p);
|
||||
}else{
|
||||
int mtgid = suite->getMTGId(action);
|
||||
int mtgid = Rules::getMTGId(action);
|
||||
if (mtgid){
|
||||
char buffe[512];
|
||||
sprintf(buffe, "TESTSUITE CARD ID : %i\n", mtgid);
|
||||
@@ -159,7 +135,7 @@ int TestSuiteAI::Act(float dt){
|
||||
if (toInterrupt)
|
||||
g->stackObjectClicked(toInterrupt);
|
||||
else{
|
||||
MTGCardInstance * card = suite->getCardByMTGId(mtgid);
|
||||
MTGCardInstance * card = Rules::getCardByMTGId(mtgid);
|
||||
if (card) {
|
||||
OutputDebugString("TESTSUITE Clicking ON: ");
|
||||
OutputDebugString(card->name.c_str());
|
||||
@@ -206,7 +182,7 @@ TestSuiteState::TestSuiteState(){
|
||||
|
||||
}
|
||||
|
||||
void TestSuiteState::parsePlayerState(int playerId, string s, TestSuite * suite){
|
||||
void TestSuiteState::parsePlayerState(int playerId, string s){
|
||||
unsigned int limiter = s.find(":");
|
||||
string areaS;
|
||||
int area;
|
||||
@@ -235,10 +211,10 @@ void TestSuiteState::parsePlayerState(int playerId, string s, TestSuite * suite)
|
||||
unsigned int value;
|
||||
limiter = s.find(",");
|
||||
if (limiter != string::npos){
|
||||
value = suite->getMTGId(s.substr(0,limiter));
|
||||
value = Rules::getMTGId(s.substr(0,limiter));
|
||||
s = s.substr(limiter+1);
|
||||
}else{
|
||||
value = suite->getMTGId(s);
|
||||
value = Rules::getMTGId(s);
|
||||
s = "";
|
||||
}
|
||||
if (value) playerData[playerId].zones[area].add(value);
|
||||
@@ -268,7 +244,7 @@ MTGPlayerCards * TestSuite::buildDeck( int playerId){
|
||||
nbcards++;
|
||||
}
|
||||
}
|
||||
MTGPlayerCards * deck = NEW MTGPlayerCards(collection, list, nbcards);
|
||||
MTGPlayerCards * deck = NEW MTGPlayerCards(list, nbcards);
|
||||
return deck;
|
||||
}
|
||||
|
||||
@@ -296,7 +272,7 @@ void TestSuite::initGame(){
|
||||
for (int j = 0; j < 4; j++){
|
||||
MTGGameZone * zone = playerZones[j];
|
||||
for (int k = 0; k < initState.playerData[i].zones[j].nbitems; k++){
|
||||
MTGCardInstance * card = getCardByMTGId(initState.playerData[i].zones[j].cards[k]);
|
||||
MTGCardInstance * card = Rules::getCardByMTGId(initState.playerData[i].zones[j].cards[k]);
|
||||
if (card && zone != p->game->library){
|
||||
if (zone == p->game->inPlay){
|
||||
MTGCardInstance * copy = p->game->putInZone(card, p->game->library, p->game->stack);
|
||||
@@ -379,7 +355,7 @@ int TestSuite::assertGame(){
|
||||
for (int k = 0; k < endState.playerData[i].zones[j].nbitems; k++){
|
||||
int cardid = endState.playerData[i].zones[j].cards[k];
|
||||
if (cardid != -1){
|
||||
MTGCardInstance * card = getCardByMTGId(cardid);
|
||||
MTGCardInstance * card = Rules::getCardByMTGId(cardid);
|
||||
if (!card || !zone->hasCard(card)){
|
||||
sprintf(result, "<span class=\"error\">==Card ID not the same. Didn't find %i</span><br />", cardid);
|
||||
Log(result);
|
||||
@@ -464,25 +440,6 @@ int TestSuite::loadNext(){
|
||||
return currentfile;
|
||||
}
|
||||
|
||||
//TODO PArses a string and gives phase numer
|
||||
int TestSuite::phaseStrToInt(string s){
|
||||
if (s.compare("untap") == 0) return Constants::MTG_PHASE_UNTAP;
|
||||
if (s.compare("upkeep") == 0)return Constants::MTG_PHASE_UPKEEP;
|
||||
if (s.compare("draw") == 0)return Constants::MTG_PHASE_DRAW;
|
||||
if (s.compare("firstmain") == 0)return Constants::MTG_PHASE_FIRSTMAIN;
|
||||
if (s.compare("combatbegin") == 0)return Constants::MTG_PHASE_COMBATBEGIN;
|
||||
if (s.compare("combatattackers") == 0)return Constants::MTG_PHASE_COMBATATTACKERS;
|
||||
if (s.compare("combatblockers") == 0)return Constants::MTG_PHASE_COMBATBLOCKERS;
|
||||
if (s.compare("combatdamage") == 0)return Constants::MTG_PHASE_COMBATDAMAGE;
|
||||
if (s.compare("combatend") == 0)return Constants::MTG_PHASE_COMBATEND;
|
||||
if (s.compare("secondmain") == 0)return Constants::MTG_PHASE_SECONDMAIN;
|
||||
if (s.compare("endofturn") == 0)return Constants::MTG_PHASE_ENDOFTURN;
|
||||
if (s.compare("cleanup") == 0)return Constants::MTG_PHASE_CLEANUP;
|
||||
OutputDebugString("TESTSUITEAI: Unknown Phase name:");
|
||||
OutputDebugString(s.c_str());
|
||||
OutputDebugString("\n");
|
||||
return Constants::MTG_PHASE_FIRSTMAIN;
|
||||
}
|
||||
|
||||
void TestSuiteActions::cleanup(){
|
||||
nbitems = 0;
|
||||
@@ -568,21 +525,21 @@ int TestSuite::load(const char * _filename){
|
||||
if (s.compare("[player1]") == 0){
|
||||
state++;
|
||||
}else{
|
||||
initState.phase = phaseStrToInt(s);
|
||||
initState.phase = PhaseRing::phaseStrToInt(s);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (s.compare("[player2]") == 0){
|
||||
state++;
|
||||
}else{
|
||||
initState.parsePlayerState(0, s,this);
|
||||
initState.parsePlayerState(0, s);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (s.compare("[do]") == 0){
|
||||
state++;
|
||||
}else{
|
||||
initState.parsePlayerState(1, s,this);
|
||||
initState.parsePlayerState(1, s);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -596,21 +553,21 @@ int TestSuite::load(const char * _filename){
|
||||
if (s.compare("[player1]") == 0){
|
||||
state++;
|
||||
}else{
|
||||
endState.phase = phaseStrToInt(s);
|
||||
endState.phase = PhaseRing::phaseStrToInt(s);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (s.compare("[player2]") == 0){
|
||||
state++;
|
||||
}else{
|
||||
endState.parsePlayerState(0, s,this);
|
||||
endState.parsePlayerState(0, s);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (s.compare("[end]") == 0){
|
||||
state++;
|
||||
}else{
|
||||
endState.parsePlayerState(1, s,this);
|
||||
endState.parsePlayerState(1, s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -616,6 +616,10 @@
|
||||
RelativePath=".\src\ReplacementEffects.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Rules.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\ShopItem.cpp"
|
||||
>
|
||||
@@ -965,6 +969,10 @@
|
||||
RelativePath=".\include\ReplacementEffects.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Rules.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\ShopItem.h"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user