Erwan
- Added Momir Basic mode :)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/ConstraintResolver.o objs/Counters.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.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/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TexturesCache.o objs/Token.o objs/utils.o objs/WEvent.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/ConstraintResolver.o objs/Counters.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.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/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TexturesCache.o objs/Token.o objs/utils.o objs/WEvent.o
|
||||
DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
|
||||
|
||||
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)
|
||||
|
||||
BIN
projects/mtg/bin/Res/graphics/momir_unlocked.png
Normal file
BIN
projects/mtg/bin/Res/graphics/momir_unlocked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
5
projects/mtg/bin/Res/player/momir.txt
Normal file
5
projects/mtg/bin/Res/player/momir.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Swamp *12
|
||||
Island *12
|
||||
Plains *12
|
||||
Mountain *12
|
||||
Forest *12
|
||||
17
projects/mtg/include/AIMomirPlayer.h
Normal file
17
projects/mtg/include/AIMomirPlayer.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _AIMOMIRPLAYER_H_
|
||||
#define _AIMOMIRPLAYER_H_
|
||||
|
||||
#include "AIPlayer.h"
|
||||
|
||||
|
||||
class AIMomirPlayer:public AIPlayerBaka{
|
||||
public:
|
||||
AIMomirPlayer(MTGPlayerCards * _deck, char * file, char * avatarFile);
|
||||
int getEfficiency(AIAction * action);
|
||||
int momir();
|
||||
int computeActions();
|
||||
static MTGAbility * momirAbility;
|
||||
static MTGAbility * getMomirAbility();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -71,6 +71,7 @@ class AIPlayer: public Player{
|
||||
int selectAbility();
|
||||
int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, map<AIAction *, int,CmpAbilities> * ranking);
|
||||
int useAbility();
|
||||
virtual int getEfficiency(AIAction * action);
|
||||
|
||||
};
|
||||
|
||||
@@ -84,7 +85,7 @@ class AIPlayerBaka: public AIPlayer{
|
||||
AIPlayerBaka(MTGPlayerCards * _deck, char * deckFile, char * avatarFile);
|
||||
virtual int Act(float dt);
|
||||
void initTimer();
|
||||
int computeActions();
|
||||
virtual int computeActions();
|
||||
};
|
||||
|
||||
class AIPlayerFactory{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "GuiLayers.h"
|
||||
#include "ActionElement.h"
|
||||
#include "SimpleMenu.h"
|
||||
#include "MTGAbility.h"
|
||||
|
||||
class GuiLayer;
|
||||
class Targetable;
|
||||
@@ -36,6 +37,7 @@ class ActionLayer: public GuiLayer, public JGuiListener{
|
||||
void ButtonPressed(int controllerid, int controlid);
|
||||
void doReactTo(int menuIndex);
|
||||
TargetChooser * getCurrentTargetChooser();
|
||||
MTGAbility * getAbility(int type);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
#define PLAYER_TYPE_TESTSUITE 2
|
||||
|
||||
|
||||
#define GAME_TYPE_CLASSIC 0
|
||||
#define GAME_TYPE_MOMIR 1
|
||||
|
||||
class MTGAllCards;
|
||||
class TexturesCache;
|
||||
|
||||
@@ -63,6 +66,7 @@ class GameApp: public JApp
|
||||
public:
|
||||
int players[2];
|
||||
MTGAllCards * collection;
|
||||
int gameType;
|
||||
TexturesCache * cache;
|
||||
|
||||
GameApp();
|
||||
|
||||
@@ -9,6 +9,7 @@ using std::string;
|
||||
#define OPTIONS_MUSICVOLUME "musicVolume"
|
||||
#define OPTIONS_SFXVOLUME "sfxVolume"
|
||||
#define OPTIONS_DIFFICULTY_MODE_UNLOCKED "prx_handler" //huhu
|
||||
#define OPTIONS_MOMIR_MODE_UNLOCKED "prx_rimom" //haha
|
||||
#define OPTIONS_DIFFICULTY "difficulty"
|
||||
|
||||
// WALDORF - added
|
||||
|
||||
@@ -33,7 +33,9 @@ class GameStateDuel: public GameState, public JGuiListener
|
||||
JQuad * unlockedQuad;
|
||||
JTexture * unlockedTex;
|
||||
int isDifficultyUnlocked();
|
||||
int isMomirUnlocked();
|
||||
void loadPlayer(int playerId, int decknb = 0, int isAI = 0);
|
||||
void loadPlayerMomir(int playerId, int isAI);
|
||||
public:
|
||||
GameStateDuel(GameApp* parent);
|
||||
virtual ~GameStateDuel();
|
||||
|
||||
@@ -11,6 +11,8 @@ class GameStateMenu: public GameState, public JGuiListener
|
||||
private:
|
||||
JGuiController* mGuiController;
|
||||
SimpleMenu* subMenuController;
|
||||
SimpleMenu* gameTypeMenu;
|
||||
int hasChosenGameType;
|
||||
JQuad * mIcons[10];
|
||||
JTexture * mIconsTexture;
|
||||
JTexture * bgTexture;
|
||||
|
||||
@@ -60,12 +60,16 @@ class MTGAbility: public ActionElement{
|
||||
virtual int resolve(){return 0;};
|
||||
|
||||
/*Poor man's casting */
|
||||
/* Todo replace that crap with dynamic casting */
|
||||
enum {
|
||||
UNKNOWN = 0,
|
||||
MANA_PRODUCER = 1,
|
||||
MTG_ATTACK_RULE = 2,
|
||||
DAMAGER = 3,
|
||||
STANDARD_REGENERATE = 4,
|
||||
PUT_INTO_PLAY = 5,
|
||||
MOMIR = 6,
|
||||
MTG_BLOCK_RULE = 7,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -85,6 +85,7 @@ class MTGPlayerCards {
|
||||
MTGInPlay * inPlay;
|
||||
MTGStack * stack;
|
||||
MTGRemovedFromGame * removedFromGame;
|
||||
MTGGameZone * garbage;
|
||||
|
||||
MTGAllCards * collection;
|
||||
|
||||
|
||||
@@ -81,62 +81,6 @@ OutputDebugString("Receive5\n");
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
class MTGPersistRule:public ListMaintainerAbility{
|
||||
public:
|
||||
MTGPersistRule(int _id):ListMaintainerAbility(_id){};
|
||||
|
||||
virtual void Update(float dt){
|
||||
map<MTGCardInstance *,bool>::iterator it;
|
||||
|
||||
for ( it=cards.begin() ; it != cards.end(); it++ ){
|
||||
MTGCardInstance * card = ((*it).first);
|
||||
Player * p = card->controller();
|
||||
if (p->game->graveyard->hasCard(card)){
|
||||
p->game->putInZone(card, p->game->graveyard, p->game->hand);
|
||||
Spell * spell = NEW Spell(card);
|
||||
p->game->putInZone(card, p->game->hand, p->game->stack);
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
card->counters->addCounter(-1,-1);
|
||||
}
|
||||
}
|
||||
|
||||
// Dirtiest Code Ever, we remove the counters here
|
||||
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = game->players[i];
|
||||
MTGGameZone * zones[] = {p->game->graveyard, p->game->hand, p->game->library, p->game->removedFromGame};
|
||||
for (int j = 0; j < 5; j++){
|
||||
MTGGameZone * zone = zones[j];
|
||||
for (int k=0; k < zone->nb_cards; k++){
|
||||
zone->cards[k]->counters->init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ListMaintainerAbility::Update(dt);
|
||||
}
|
||||
|
||||
int canBeInList(MTGCardInstance * card){
|
||||
if (card->basicAbilities[Constants::PERSIST] && !card->counters->hasCounter(-1,-1) ){
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
OutputDebugString("yay, persist !\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int added(MTGCardInstance * card){return 1;}
|
||||
|
||||
int removed(MTGCardInstance * card){return 0;}
|
||||
|
||||
int testDestroy(){return 0;}
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Rule 420.5e (Legend Rule)
|
||||
@@ -176,4 +120,18 @@ class MTGLegendRule:public ListMaintainerAbility{
|
||||
int testDestroy(){return 0;}
|
||||
};
|
||||
|
||||
|
||||
class MTGMomirRule:public MTGAbility{
|
||||
public:
|
||||
int alreadyplayed;
|
||||
MTGAllCards * collection;
|
||||
MTGCardInstance * genRandomCreature(int convertedCost);
|
||||
int testDestroy();
|
||||
void Update(float dt);
|
||||
MTGMomirRule(int _id, MTGAllCards * _collection);
|
||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||
int reactToClick(MTGCardInstance * card);
|
||||
const char * getMenuText(){return "Momir";}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@ class ManaCost{
|
||||
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL);
|
||||
void init();
|
||||
void x();
|
||||
ManaCost(int _cost[], int nb_elems);
|
||||
ManaCost(int _cost[], int nb_elems = 1);
|
||||
ManaCost();
|
||||
~ManaCost();
|
||||
ManaCost(ManaCost * _manaCost);
|
||||
|
||||
192
projects/mtg/src/AIMomirPlayer.cpp
Normal file
192
projects/mtg/src/AIMomirPlayer.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "../include/config.h"
|
||||
#include "../include/AIMomirPlayer.h"
|
||||
#include "../include/CardDescriptor.h"
|
||||
#include "../include/DamageResolverLayer.h"
|
||||
#include "../include/DamagerDamaged.h"
|
||||
#include "../include/AIStats.h"
|
||||
#include "../include/AllAbilities.h"
|
||||
|
||||
|
||||
MTGAbility * AIMomirPlayer::momirAbility = NULL;
|
||||
|
||||
AIMomirPlayer::AIMomirPlayer(MTGPlayerCards * _deck, char * file, char * avatarFile): AIPlayerBaka(_deck,file, avatarFile){
|
||||
// TODO count min and max number of mana (should probably be part of the gameobserver so that human players don't make mistakes)
|
||||
momirAbility = NULL;
|
||||
}
|
||||
|
||||
int AIMomirPlayer::getEfficiency(AIAction * action){
|
||||
|
||||
|
||||
int efficiency = AIPlayerBaka::getEfficiency(action);
|
||||
if (efficiency < 15) return 0;
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (g->getCurrentGamePhase() < Constants::MTG_PHASE_FIRSTMAIN) return 0;
|
||||
return efficiency;
|
||||
}
|
||||
|
||||
MTGAbility * AIMomirPlayer::getMomirAbility(){
|
||||
if (momirAbility) return momirAbility;
|
||||
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
momirAbility = g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR);
|
||||
return momirAbility;
|
||||
}
|
||||
|
||||
int AIMomirPlayer::momir(){
|
||||
if (!game->hand->nb_cards) return 0; //nothing to discard :/
|
||||
getPotentialMana();
|
||||
int converted = potentialMana->getConvertedCost();
|
||||
int efficiency = 100;
|
||||
int chance = 1 + (rand() % 100);
|
||||
if (converted == 5) efficiency = 5 ; //Strategy: skip 5 drop
|
||||
if (converted == 7) efficiency = 50; //Strategy: 7 drops have bad upkeep costs and the AI doesn't handle those right now...
|
||||
if (converted > 8 ) converted = 8;
|
||||
if (converted == 8) efficiency = 100 - game->inPlay->nb_cards;
|
||||
|
||||
if (efficiency >= chance){
|
||||
int _cost[] = {Constants::MTG_COLOR_ARTIFACT,converted};
|
||||
ManaCost * cost = NEW ManaCost(_cost);
|
||||
tapLandsForMana(potentialMana,cost);
|
||||
delete cost;
|
||||
MTGAbility * ability = getMomirAbility();
|
||||
MTGCardInstance * card = game->hand->cards[0];
|
||||
if (ability->isReactingToClick(card,cost)){
|
||||
AIAction * a = NEW AIAction(ability,card);
|
||||
clickstream.push(a);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AIMomirPlayer::computeActions(){
|
||||
//Part of the strategy goes here. When should we put a land into play ?
|
||||
/*
|
||||
Another gift from Alex Majlaton on my first day playing Momir, and it has served me well ever since. It goes a little something like this: (a) if you are on the play, hit your Two through Four, skip your Five, and then hit all the way to Eight; (b) if you are on the draw and your opponent skips his One, you make Two through Eight; (c) if you are on the draw and your opponent hits a One, you match him drop-for-drop for the rest of the game.
|
||||
|
||||
You skip your Five on the play because it is the weakest drop. There are plenty of serviceable guys there, but very few bombs compared to other drops
|
||||
the general rule is this: if you want to get to Eight, you have to skip two drops on the play and one drop on the draw.
|
||||
*/
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
Player * p = g->currentPlayer;
|
||||
if (!(g->currentlyActing() == this)) return 0;
|
||||
if (chooseTarget()) return 1;
|
||||
int currentGamePhase = g->getCurrentGamePhase();
|
||||
if (g->isInterrupting == this){ // interrupting
|
||||
selectAbility();
|
||||
return 1;
|
||||
}else if (p == this && g->mLayers->stackLayer()->count(0,NOT_RESOLVED) == 0){ //standard actions
|
||||
CardDescriptor cd;
|
||||
MTGCardInstance * card = NULL;
|
||||
//No mana, try to get some
|
||||
getPotentialMana();
|
||||
|
||||
|
||||
switch(currentGamePhase){
|
||||
case Constants::MTG_PHASE_FIRSTMAIN:
|
||||
if (canPutLandsIntoPlay && (potentialMana->getConvertedCost() <8 || game->hand->nb_cards > 1) ){
|
||||
//Attempt to put land into play
|
||||
cd.init();
|
||||
cd.setColor(Constants::MTG_COLOR_LAND);
|
||||
card = cd.match(game->hand);
|
||||
if (card){
|
||||
MTGAbility * putIntoPlay = g->mLayers->actionLayer()->getAbility(MTGAbility::PUT_INTO_PLAY);
|
||||
AIAction * a = NEW AIAction(putIntoPlay,card); //TODO putinplay action
|
||||
clickstream.push(a);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
momir();
|
||||
return 1;
|
||||
break;
|
||||
case Constants::MTG_PHASE_SECONDMAIN:
|
||||
selectAbility();
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return AIPlayerBaka::computeActions();
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
return AIPlayerBaka::computeActions();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
int AIPlayerBaka::computeActions(){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
Player * p = g->currentPlayer;
|
||||
if (!(g->currentlyActing() == this)) return 0;
|
||||
if (chooseTarget()) return 1;
|
||||
int currentGamePhase = g->getCurrentGamePhase();
|
||||
if (g->isInterrupting == this){ // interrupting
|
||||
selectAbility();
|
||||
return 1;
|
||||
}else if (p == this && g->mLayers->stackLayer()->count(0,NOT_RESOLVED) == 0){ //standard actions
|
||||
CardDescriptor cd;
|
||||
MTGCardInstance * card = NULL;
|
||||
switch(currentGamePhase){
|
||||
case Constants::MTG_PHASE_FIRSTMAIN:
|
||||
case Constants::MTG_PHASE_SECONDMAIN:
|
||||
if (canPutLandsIntoPlay){
|
||||
//Attempt to put land into play
|
||||
cd.init();
|
||||
cd.setColor(Constants::MTG_COLOR_LAND);
|
||||
card = cd.match(game->hand);
|
||||
if (card){
|
||||
AIAction * a = NEW AIAction(card);
|
||||
clickstream.push(a);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//No mana, try to get some
|
||||
getPotentialMana();
|
||||
if (potentialMana->getConvertedCost() > 0){
|
||||
|
||||
|
||||
//look for the most expensive creature we can afford
|
||||
nextCardToPlay = FindCardToPlay(potentialMana, "creature");
|
||||
//Let's Try an enchantment maybe ?
|
||||
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "enchantment");
|
||||
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "artifact");
|
||||
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "instant");
|
||||
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "sorcery");
|
||||
if (nextCardToPlay){
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
char buffe[4096];
|
||||
sprintf(buffe, "Putting Card Into Play: %s", nextCardToPlay->getName());
|
||||
OutputDebugString(buffe);
|
||||
#endif
|
||||
|
||||
tapLandsForMana(potentialMana,nextCardToPlay->getManaCost());
|
||||
AIAction * a = NEW AIAction(nextCardToPlay);
|
||||
clickstream.push(a);
|
||||
return 1;
|
||||
}else{
|
||||
selectAbility();
|
||||
}
|
||||
}else{
|
||||
selectAbility();
|
||||
}
|
||||
break;
|
||||
case Constants::MTG_PHASE_COMBATATTACKERS:
|
||||
chooseAttackers();
|
||||
break;
|
||||
default:
|
||||
selectAbility();
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
switch(currentGamePhase){
|
||||
case Constants::MTG_PHASE_COMBATBLOCKERS:
|
||||
chooseBlockers();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
*/
|
||||
@@ -121,6 +121,10 @@ ManaCost * AIPlayer::getPotentialMana(){
|
||||
}
|
||||
|
||||
|
||||
int AIPlayer::getEfficiency(AIAction * action){
|
||||
return action->getEfficiency();
|
||||
}
|
||||
|
||||
int AIAction::getEfficiency(){
|
||||
//TODO add multiplier according to what the player wants
|
||||
if (efficiency != -1) return efficiency;
|
||||
@@ -129,6 +133,7 @@ int AIAction::getEfficiency(){
|
||||
ActionStack * s = g->mLayers->stackLayer();
|
||||
Player * p = g->currentlyActing();
|
||||
if (s->has(ability)) return 0;
|
||||
if (ability->cost && !(ability->cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet
|
||||
switch (ability->aType){
|
||||
case MTGAbility::DAMAGER:
|
||||
{
|
||||
@@ -226,7 +231,7 @@ int AIPlayer::selectAbility(){
|
||||
OutputDebugString("We have a winner\n");
|
||||
AIAction * a = ranking.begin()->first;
|
||||
int chance = 1 + rand() % 100;
|
||||
if (a->getEfficiency() < chance){
|
||||
if (getEfficiency(a) < chance){
|
||||
a = NULL;
|
||||
}else{
|
||||
OutputDebugString("We REALLY have a winner\n");
|
||||
@@ -262,6 +267,8 @@ int AIPlayer::effectBadOrGood(MTGCardInstance * card){
|
||||
return BAKA_EFFECT_DONTKNOW;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AIPlayer::chooseTarget(TargetChooser * tc){
|
||||
Targetable * potentialTargets[50];
|
||||
int nbtargets = 0;
|
||||
@@ -393,24 +400,25 @@ int AIPlayer::chooseBlockers(){
|
||||
cd.setType("Creature");
|
||||
cd.tapped = -1;
|
||||
MTGCardInstance * card = NULL;
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
while((card = cd.nextmatch(game->inPlay, card))){
|
||||
GameObserver::GetInstance()->cardClick(card);
|
||||
g->cardClick(card);
|
||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
||||
int set = 0;
|
||||
while(!set){
|
||||
if (!card->defenser){
|
||||
set = 1;
|
||||
set = 1;
|
||||
}else{
|
||||
MTGCardInstance * attacker = card->defenser;
|
||||
map<MTGCardInstance *,int>::iterator it = opponentsToughness.find(attacker);
|
||||
if ( it == opponentsToughness.end()){
|
||||
opponentsToughness[attacker] = attacker->toughness;
|
||||
it = opponentsToughness.find(attacker);
|
||||
}
|
||||
if (opponentsToughness[attacker] > 0 && getStats() && getStats()->isInTop(attacker,3,false)){
|
||||
opponentsToughness[attacker]-= card->power;
|
||||
set = 1;
|
||||
}else{
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
MTGCardInstance * attacker = card->defenser;
|
||||
map<MTGCardInstance *,int>::iterator it = opponentsToughness.find(attacker);
|
||||
if ( it == opponentsToughness.end()){
|
||||
opponentsToughness[attacker] = attacker->toughness;
|
||||
it = opponentsToughness.find(attacker);
|
||||
}
|
||||
if (opponentsToughness[attacker] > 0 && getStats() && getStats()->isInTop(attacker,3,false)){
|
||||
opponentsToughness[attacker]-= card->power;
|
||||
set = 1;
|
||||
}else{
|
||||
g->cardClick(card);
|
||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
||||
}
|
||||
@@ -421,7 +429,7 @@ int AIPlayer::chooseBlockers(){
|
||||
while((card = cd.nextmatch(game->inPlay, card))){
|
||||
if (card->defenser && opponentsToughness[card->defenser] > 0){
|
||||
while (card->defenser){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
|
||||
g->cardClick(card);
|
||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
||||
}
|
||||
@@ -430,7 +438,6 @@ int AIPlayer::chooseBlockers(){
|
||||
card = NULL;
|
||||
while((card = cd.nextmatch(game->inPlay, card))){
|
||||
if(!card->defenser){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
g->cardClick(card);
|
||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
||||
int set = 0;
|
||||
@@ -440,7 +447,6 @@ int AIPlayer::chooseBlockers(){
|
||||
}else{
|
||||
MTGCardInstance * attacker = card->defenser;
|
||||
if (opponentsToughness[attacker] <= 0 || (card->toughness <= card->defenser->power && opponentForce*2 <life) || card->defenser->nbOpponents()>1){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
g->cardClick(card);
|
||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
||||
}else{
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
#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::unstopableRenderInProgress(){
|
||||
|
||||
for (int i=0;i<mCount;i++){
|
||||
|
||||
@@ -38,8 +38,8 @@ GameApp::GameApp(): JApp()
|
||||
mShowDebugInfo = false;
|
||||
players[0] = 0;
|
||||
players[1] = 0;
|
||||
|
||||
|
||||
gameType = GAME_TYPE_CLASSIC;
|
||||
//gameType = GAME_TYPE_MOMIR;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -109,6 +109,10 @@ void GameObserver::nextGamePhase(){
|
||||
}
|
||||
mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn;
|
||||
mLayers->actionLayer()->Update(0);
|
||||
for (int i=0; i < 2; i++){
|
||||
delete (players[i]->game->garbage);
|
||||
players[i]->game->garbage = NEW MTGGameZone();
|
||||
}
|
||||
return nextGamePhase();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
#include "../include/GameOptions.h"
|
||||
#include "../include/utils.h"
|
||||
#include "../include/AIPlayer.h"
|
||||
#include "../include/AIMomirPlayer.h"
|
||||
#include "../include/PlayerData.h"
|
||||
#include "../include/DeckStats.h"
|
||||
|
||||
#include "../include/MTGRules.h"
|
||||
|
||||
#ifdef TESTSUITE
|
||||
#include "../include/TestSuiteAI.h"
|
||||
@@ -89,18 +90,18 @@ void GameStateDuel::Start()
|
||||
for (int i = 0; i<2; i ++){
|
||||
if (mParent->players[i] == PLAYER_TYPE_HUMAN){
|
||||
if (!deckmenu){
|
||||
decksneeded = 1;
|
||||
deckmenu = NEW SimpleMenu(DUEL_MENU_CHOOSE_DECK, this, mFont, 35, 25, "Choose a Deck");
|
||||
char buffer[100];
|
||||
for (int j=1; j<6; j++){
|
||||
sprintf(buffer, RESPATH"/player/deck%i.txt",j);
|
||||
std::ifstream file(buffer);
|
||||
if(file){
|
||||
deckmenu->Add(j, GameState::menuTexts[j]);
|
||||
file.close();
|
||||
decksneeded = 0;
|
||||
}
|
||||
}
|
||||
decksneeded = 1;
|
||||
deckmenu = NEW SimpleMenu(DUEL_MENU_CHOOSE_DECK, this, mFont, 35, 25, "Choose a Deck");
|
||||
char buffer[100];
|
||||
for (int j=1; j<6; j++){
|
||||
sprintf(buffer, RESPATH"/player/deck%i.txt",j);
|
||||
std::ifstream file(buffer);
|
||||
if(file){
|
||||
deckmenu->Add(j, GameState::menuTexts[j]);
|
||||
file.close();
|
||||
decksneeded = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,6 +111,19 @@ void GameStateDuel::Start()
|
||||
}
|
||||
|
||||
|
||||
void GameStateDuel::loadPlayerMomir(int playerId, int isAI){
|
||||
char * deckFile = RESPATH"/player/momir.txt";
|
||||
char * deckFileSmall = "momir";
|
||||
MTGDeck * tempDeck = NEW MTGDeck(deckFile, NULL, mParent->collection);
|
||||
deck[playerId] = NEW MTGPlayerCards(mParent->collection,tempDeck);
|
||||
if (!isAI){ //Human Player
|
||||
mPlayers[playerId] = NEW HumanPlayer(deck[playerId],deckFileSmall);
|
||||
}else{
|
||||
mPlayers[playerId] = NEW AIMomirPlayer(deck[playerId],deckFile,"");
|
||||
}
|
||||
delete tempDeck;
|
||||
}
|
||||
|
||||
void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){
|
||||
if (decknb){
|
||||
if (!isAI){ //Human Player
|
||||
@@ -197,7 +211,14 @@ void GameStateDuel::Update(float dt)
|
||||
mParent->SetNextState(GAME_STATE_DECK_VIEWER);
|
||||
break;
|
||||
case DUEL_STATE_CHOOSE_DECK1:
|
||||
if (mParent->players[0] == PLAYER_TYPE_HUMAN)
|
||||
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);
|
||||
}
|
||||
mGamePhase = DUEL_STATE_PLAY;
|
||||
}else if (mParent->players[0] == PLAYER_TYPE_HUMAN)
|
||||
deckmenu->Update(dt);
|
||||
#ifdef TESTSUITE
|
||||
else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){
|
||||
@@ -280,13 +301,19 @@ void GameStateDuel::Update(float dt)
|
||||
case DUEL_STATE_PLAY:
|
||||
//Stop the music before starting the game
|
||||
if (GameApp::music){
|
||||
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
|
||||
SAFE_DELETE(GameApp::music);
|
||||
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
|
||||
SAFE_DELETE(GameApp::music);
|
||||
}
|
||||
if (!game){
|
||||
GameObserver::Init(mPlayers, 2);
|
||||
game = GameObserver::GetInstance();
|
||||
game->startGame();
|
||||
GameObserver::Init(mPlayers, 2);
|
||||
game = GameObserver::GetInstance();
|
||||
game->startGame();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
game->Update(dt);
|
||||
if (game->gameOver){
|
||||
@@ -303,6 +330,16 @@ void GameStateDuel::Update(float dt)
|
||||
unlockedQuad = NEW JQuad(unlockedTex, 2, 2, 396, 96);
|
||||
GameOptions::GetInstance()->values[OPTIONS_DIFFICULTY_MODE_UNLOCKED] = GameOption(1);
|
||||
GameOptions::GetInstance()->save();
|
||||
}else{
|
||||
unlocked = isMomirUnlocked();
|
||||
if (unlocked){
|
||||
unlockedTex = JRenderer::GetInstance()->LoadTexture("graphics/momir_unlocked.png", TEX_TYPE_USE_VRAM);
|
||||
unlockedQuad = NEW JQuad(unlockedTex, 2, 2, 396, 96);
|
||||
GameOptions::GetInstance()->values[OPTIONS_MOMIR_MODE_UNLOCKED] = GameOption(1);
|
||||
GameOptions::GetInstance()->save();
|
||||
}
|
||||
}
|
||||
if (unlocked){
|
||||
JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/bonus.wav");
|
||||
if (sample) JSoundSystem::GetInstance()->PlaySample(sample);
|
||||
}
|
||||
@@ -496,4 +533,11 @@ int GameStateDuel::isDifficultyUnlocked(){
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GameStateDuel::isMomirUnlocked(){
|
||||
if (GameOptions::GetInstance()->values[OPTIONS_MOMIR_MODE_UNLOCKED].getIntValue()) return 0;
|
||||
Player *p = mPlayers[0];
|
||||
if (p->game->inPlay->countByType("land") == 8) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -47,7 +47,9 @@ enum
|
||||
SUBMENUITEM_2PLAYER,
|
||||
SUBMENUITEM_DEMO,
|
||||
SUBMENUITEM_CANCEL,
|
||||
SUBMENUITEM_TESTSUITE
|
||||
SUBMENUITEM_TESTSUITE,
|
||||
SUBMENUITEM_MOMIR,
|
||||
SUBMENUITEM_CLASSIC,
|
||||
};
|
||||
|
||||
|
||||
@@ -55,6 +57,7 @@ GameStateMenu::GameStateMenu(GameApp* parent): GameState(parent)
|
||||
{
|
||||
mGuiController = NULL;
|
||||
subMenuController = NULL;
|
||||
gameTypeMenu = NULL;
|
||||
mIconsTexture = NULL;
|
||||
//bgMusic = NULL;
|
||||
timeIndex = 0;
|
||||
@@ -118,6 +121,7 @@ void GameStateMenu::Destroy()
|
||||
{
|
||||
SAFE_DELETE(mGuiController);
|
||||
SAFE_DELETE(subMenuController);
|
||||
SAFE_DELETE(gameTypeMenu);
|
||||
SAFE_DELETE(mIconsTexture);
|
||||
|
||||
for (int i = 0; i < 10 ; i++){
|
||||
@@ -148,6 +152,9 @@ void GameStateMenu::Start(){
|
||||
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
|
||||
SAFE_DELETE(GameApp::music);
|
||||
}
|
||||
|
||||
hasChosenGameType = 1;
|
||||
if (GameOptions::GetInstance()->values[OPTIONS_MOMIR_MODE_UNLOCKED].getIntValue()) hasChosenGameType =0;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,13 +183,7 @@ int GameStateMenu::nextCardSet(){
|
||||
|
||||
void GameStateMenu::End()
|
||||
{
|
||||
//mEngine->EnableVSync(false);
|
||||
|
||||
// if (bgMusic)
|
||||
// {
|
||||
//JSoundSystem::GetInstance()->StopMusic(bgMusic);
|
||||
//SAFE_DELETE(bgMusic);
|
||||
// }
|
||||
JRenderer::GetInstance()->EnableVSync(false);
|
||||
}
|
||||
|
||||
@@ -190,14 +191,6 @@ void GameStateMenu::End()
|
||||
|
||||
void GameStateMenu::Update(float dt)
|
||||
{
|
||||
/*
|
||||
if (GameApp::music){
|
||||
if (mVolume < 2*GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME]){
|
||||
mVolume++;
|
||||
JSoundSystem::GetInstance()->SetVolume(mVolume/2);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
timeIndex += dt * 2;
|
||||
switch (MENU_STATE_MAJOR & currentState)
|
||||
@@ -258,8 +251,19 @@ void GameStateMenu::Update(float dt)
|
||||
case MENU_STATE_MAJOR_DUEL :
|
||||
if (MENU_STATE_MINOR_NONE == (currentState & MENU_STATE_MINOR))
|
||||
{
|
||||
mParent->SetNextState(GAME_STATE_DUEL);
|
||||
currentState = MENU_STATE_MAJOR_MAINMENU;
|
||||
if (!hasChosenGameType){
|
||||
currentState = MENU_STATE_MAJOR_SUBMENU;
|
||||
JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT);
|
||||
subMenuController = NEW SimpleMenu(102, this, mFont, 150,60);
|
||||
if (subMenuController){
|
||||
subMenuController->Add(SUBMENUITEM_CLASSIC,"Classic");
|
||||
subMenuController->Add(SUBMENUITEM_MOMIR, "Momir Basic");
|
||||
subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel");
|
||||
}
|
||||
}else{
|
||||
mParent->SetNextState(GAME_STATE_DUEL);
|
||||
currentState = MENU_STATE_MAJOR_MAINMENU;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (MENU_STATE_MINOR & currentState)
|
||||
@@ -423,23 +427,18 @@ JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT);
|
||||
switch (controlId)
|
||||
{
|
||||
case MENUITEM_PLAY:
|
||||
|
||||
subMenuController = NEW SimpleMenu(102, this, mFont, 150,60);
|
||||
if (subMenuController){
|
||||
subMenuController->Add(SUBMENUITEM_1PLAYER,"1 Player");
|
||||
subMenuController->Add(SUBMENUITEM_2PLAYER, "2 Players");
|
||||
subMenuController->Add(SUBMENUITEM_DEMO,"Demo");
|
||||
subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel");
|
||||
#ifdef TESTSUITE
|
||||
subMenuController = NEW SimpleMenu(102, this, mFont, 150,60);
|
||||
#else
|
||||
subMenuController = NEW SimpleMenu(102, this, mFont, 150,60);
|
||||
#endif
|
||||
if (subMenuController){
|
||||
subMenuController->Add(SUBMENUITEM_1PLAYER,"1 Player");
|
||||
subMenuController->Add(SUBMENUITEM_2PLAYER, "2 Players");
|
||||
subMenuController->Add(SUBMENUITEM_DEMO,"Demo");
|
||||
subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel");
|
||||
#ifdef TESTSUITE
|
||||
subMenuController->Add(SUBMENUITEM_TESTSUITE, "Test Suite");
|
||||
subMenuController->Add(SUBMENUITEM_TESTSUITE, "Test Suite");
|
||||
#endif
|
||||
currentState = MENU_STATE_MAJOR_SUBMENU | MENU_STATE_MINOR_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MENUITEM_DECKEDITOR:
|
||||
mParent->SetNextState(GAME_STATE_DECK_VIEWER);
|
||||
break;
|
||||
@@ -474,6 +473,20 @@ JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT);
|
||||
subMenuController->Close();
|
||||
currentState = MENU_STATE_MAJOR_MAINMENU | MENU_STATE_MINOR_SUBMENU_CLOSING;
|
||||
break;
|
||||
|
||||
case SUBMENUITEM_CLASSIC:
|
||||
this->hasChosenGameType = 1;
|
||||
mParent->gameType = GAME_TYPE_CLASSIC;
|
||||
subMenuController->Close();
|
||||
currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING;
|
||||
break;
|
||||
|
||||
case SUBMENUITEM_MOMIR:
|
||||
this->hasChosenGameType = 1;
|
||||
mParent->gameType = GAME_TYPE_MOMIR;
|
||||
subMenuController->Close();
|
||||
currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING;
|
||||
break;
|
||||
#ifdef TESTSUITE
|
||||
case SUBMENUITEM_TESTSUITE:
|
||||
mParent->players[0] = PLAYER_TYPE_TESTSUITE;
|
||||
|
||||
@@ -54,6 +54,7 @@ MTGPlayerCards::~MTGPlayerCards(){
|
||||
SAFE_DELETE(inPlay);
|
||||
SAFE_DELETE(stack);
|
||||
SAFE_DELETE(removedFromGame);
|
||||
SAFE_DELETE(garbage);
|
||||
}
|
||||
|
||||
void MTGPlayerCards::setOwner(Player * player){
|
||||
@@ -82,6 +83,7 @@ void MTGPlayerCards::init(){
|
||||
inPlay = NEW MTGInPlay();
|
||||
stack = NEW MTGStack();
|
||||
removedFromGame = NEW MTGRemovedFromGame();
|
||||
garbage = NEW MTGGameZone();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,8 +132,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
||||
|
||||
if (card->isToken){
|
||||
if (to != g->players[0]->game->inPlay && to != g->players[1]->game->inPlay){
|
||||
//Token leaves play: we destroy it
|
||||
//TODO DELETE Object
|
||||
garbage->addCard(copy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "../include/MTGRules.h"
|
||||
|
||||
MTGPutInPlayRule::MTGPutInPlayRule(int _id):MTGAbility(_id, NULL){
|
||||
|
||||
aType=MTGAbility::PUT_INTO_PLAY;
|
||||
}
|
||||
|
||||
int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
||||
@@ -78,6 +78,7 @@ int MTGPutInPlayRule::testDestroy(){
|
||||
}
|
||||
|
||||
MTGAttackRule::MTGAttackRule(int _id):MTGAbility(_id,NULL){
|
||||
aType=MTGAbility::MTG_ATTACK_RULE;
|
||||
}
|
||||
|
||||
int MTGAttackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
||||
@@ -102,6 +103,7 @@ int MTGAttackRule::testDestroy(){
|
||||
|
||||
|
||||
MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){
|
||||
aType=MTGAbility::MTG_BLOCK_RULE;
|
||||
}
|
||||
|
||||
int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
||||
@@ -134,3 +136,74 @@ int MTGBlockRule::reactToClick(MTGCardInstance * card){
|
||||
int MTGBlockRule::testDestroy(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// * Momir
|
||||
//
|
||||
|
||||
MTGMomirRule::MTGMomirRule(int _id, MTGAllCards * _collection):MTGAbility(_id, NULL){
|
||||
collection = _collection;
|
||||
alreadyplayed = 0;
|
||||
aType=MTGAbility::MOMIR;
|
||||
}
|
||||
|
||||
int MTGMomirRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
||||
if (alreadyplayed) return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
Player * currentPlayer = game->currentPlayer;
|
||||
LOG("CANPUTINPLAY- check if card belongs to current player\n");
|
||||
if (!player->game->hand->hasCard(card)) return 0;
|
||||
LOG("CANPUTINPLAY- check if card is land or can be played\n");
|
||||
if (player == currentPlayer && !game->isInterrupting && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)){
|
||||
LOG("CANPUTINPLAY- correct time to play\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGMomirRule::reactToClick(MTGCardInstance * card_to_discard){
|
||||
if (!isReactingToClick(card_to_discard)) return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * cost = player->getManaPool();
|
||||
int converted = cost->getConvertedCost();
|
||||
player->getManaPool()->pay(cost);
|
||||
player->game->putInZone(card_to_discard, player->game->hand, player->game->graveyard);
|
||||
MTGCardInstance * card = genRandomCreature(converted); //TODO code this function
|
||||
player->game->stack->addCard(card);
|
||||
Spell * spell = NEW Spell(card);
|
||||
spell->resolve();
|
||||
spell->source->isToken = 1;
|
||||
delete spell;
|
||||
alreadyplayed = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
MTGCardInstance * MTGMomirRule::genRandomCreature(int convertedCost){
|
||||
Player * p = game->currentlyActing();
|
||||
int total_cards = collection->totalCards();
|
||||
int start = (rand() % total_cards);
|
||||
int id2 = start;
|
||||
while (id2 < total_cards){
|
||||
MTGCard * card = collection->collection[id2];
|
||||
if (card->isACreature() && card->getManaCost()->getConvertedCost() == convertedCost){
|
||||
return NEW MTGCardInstance(card,p->game);
|
||||
}
|
||||
id2++;
|
||||
if (id2 == start) return NULL;
|
||||
if (id2 == total_cards) id2 = 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//The Momir rule is never destroyed
|
||||
int MTGMomirRule::testDestroy(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MTGMomirRule::Update(float dt){
|
||||
if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){
|
||||
alreadyplayed = 0;
|
||||
}
|
||||
MTGAbility::Update(dt);
|
||||
}
|
||||
|
||||
@@ -228,6 +228,10 @@
|
||||
RelativePath=".\src\ActionStack.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\AIMomirPlayer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\AIPlayer.cpp"
|
||||
>
|
||||
@@ -529,6 +533,10 @@
|
||||
RelativePath=".\include\ActionStack.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\AIMomirPlayer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\AIPlayer.h"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user