- Magic 2010 - blockers ordering
- Fixed a memory leak introduced in a previous revision (foreach)
This commit is contained in:
wagic.the.homebrew@gmail.com
2009-07-04 04:15:05 +00:00
parent dfeada17a2
commit d52f06d98d
22 changed files with 580 additions and 253 deletions

View File

@@ -2,6 +2,7 @@
#Generic engine features
########################
generic/attacks_each_turn.txt
generic/m10_blockers.txt
generic/first_strike.txt
generic/first_strike2.txt
generic/first_strike3.txt

View File

@@ -0,0 +1,28 @@
#New blockers reordering rule
[INIT]
COMBATATTACKERS
[PLAYER1]
inplay:Puppeteer
[PLAYER2]
inplay:raging goblin,Drudge Skeletons
[DO]
Puppeteer
next
#blockers
raging goblin
Drudge Skeletons
next
#blockers order
Drudge Skeletons
next
#combat damage
next
#combat end
[ASSERT]
COMBATEND
[PLAYER1]
graveyard:Puppeteer
[PLAYER2]
graveyard:Drudge Skeletons
inplay:raging goblin
[END]

View File

@@ -51,6 +51,7 @@ class AIPlayer: public Player{
ManaCost * potentialMana;
queue<AIAction *> clickstream;
void tapLandsForMana(ManaCost * potentialMana, ManaCost * cost);
int orderBlockers();
int combatDamages();
int interruptIfICan();
int chooseAttackers();

View File

@@ -931,17 +931,17 @@ class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{
//Untap Blockers with simple Mana Mechanism
class AUntapManaBlocker: public Blocker{
class AUntapManaBlocker: public UntapBlocker{
public:
AUntapManaBlocker(int id, MTGCardInstance * card, ManaCost * _cost):Blocker(id, card, _cost){
AUntapManaBlocker(int id, MTGCardInstance * card, ManaCost * _cost):UntapBlocker(id, card, _cost){
}
AUntapManaBlocker(int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost):Blocker(id, card,_target, _cost){
AUntapManaBlocker(int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost):UntapBlocker(id, card,_target, _cost){
}
virtual ostream& toString(ostream& out) const
{
out << "AUntapManaBlocker ::: (";
return Blocker::toString(out) << ")";
return UntapBlocker::toString(out) << ")";
}
};

View File

@@ -12,7 +12,7 @@ class ManaCost;
class GameObserver;
class MTGAbility;
class Blocker : public MTGAbility {
class UntapBlocker : public MTGAbility {
protected:
ManaCost * manaCost;
int currentPhase;
@@ -20,28 +20,28 @@ class Blocker : public MTGAbility {
public:
virtual ManaCost * untapManaCost(){return manaCost;};
virtual int unblock(){return 1;};
Blocker(int id, MTGCardInstance * card, ManaCost * _cost);
Blocker(int id, MTGCardInstance * card);
Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target);
Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost);
~Blocker();
UntapBlocker(int id, MTGCardInstance * card, ManaCost * _cost);
UntapBlocker(int id, MTGCardInstance * card);
UntapBlocker(int id, MTGCardInstance * card, MTGCardInstance *_target);
UntapBlocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost);
~UntapBlocker();
virtual void Update(float dt);
virtual int destroy();
};
class Blockers {
class UntapBlockers {
protected:
int cursor;
int blockers[MAX_BLOCKERS];
GameObserver * game;
public:
Blockers();
~Blockers();
int Add (Blocker * ability);
int Remove (Blocker * ability);
UntapBlockers();
~UntapBlockers();
int Add (UntapBlocker * ability);
int Remove (UntapBlocker * ability);
int init();
Blocker * next();
UntapBlocker * next();
int rewind();
int isEmpty();
};

View File

@@ -10,8 +10,11 @@ class DamageStack;
class DamageResolverLayer:public PlayGuiObjectController{
protected:
int trampleDamage();
void updateAllCoordinates();
public:
int buttonOk;
int orderingIsNeeded;
int currentPhase;
int remainingDamageSteps;
Player * currentChoosingPlayer;
@@ -23,16 +26,26 @@ class DamageResolverLayer:public PlayGuiObjectController{
int initResolve();
Player * whoSelectsDamagesDealtBy(MTGCardInstance * card);
int addAutoDamageToOpponents(MTGCardInstance * card);
int addIfNotExists(MTGCardInstance * card, Player * selecter);
DamagerDamaged * addIfNotExists(MTGCardInstance * card, Player * selecter);
int addDamager(MTGCardInstance * card, Player * selecter);
int updateCoordinates(MTGCardInstance * card);
DamagerDamaged * findByCard(MTGCardInstance * card);
int canStopDealDamages();
int resolveDamages();
int isOpponent(DamagerDamaged * a, DamagerDamaged * b);
void nextPlayer();
int nextPlayer();
virtual void Update(float dt);
virtual bool CheckUserInput(u32 key);
virtual void Render();
int isDisplayed(){return mCount;};
int autoOrderBlockers();
bool blockersOrderingDone();
bool clickDamage(DamagerDamaged * current);
bool clickDamage(MTGCardInstance * c);
bool clickReorderBlocker(MTGCardInstance * blocker);
bool checkUserInputOrderBlockers(u32 key);
};
#endif

View File

@@ -28,10 +28,11 @@ class GameObserver{
int nbPlayers;
int currentPlayerId;
int currentRound;
int blockersAssigned;
public:
int blockersSorted;
int forceShuffleLibrary[2];
int turn;
int forceShuffleLibraries();

View File

@@ -17,11 +17,12 @@ class MTGAbility;
class MTGCard;
class TexturesCache;
class ManaCost;
class Blockers;
class UntapBlockers;
class CardDescriptor;
class Counters;
#include <list>
using namespace std;
class MTGCardInstance: public MTGCard, public Damageable {
protected:
@@ -31,9 +32,9 @@ class MTGCardInstance: public MTGCard, public Damageable {
int tapped;
int lifeOrig;
Blockers * blockers;
UntapBlockers * untapBlockers;
MTGPlayerCards * belongs_to;
MTGAbility * UntapBlockers[10];
MTGAbility * untapBlockerAbilities[10];
void unband();
MTGCardInstance * getNextPartner();
void initMTGCI();
@@ -51,38 +52,47 @@ class MTGCardInstance: public MTGCard, public Damageable {
// The recommended method to test for summoning Sickness !
int hasSummoningSickness();
MTGCardInstance * changeController(Player * newcontroller);
MTGCardInstance * defenser;
float changedZoneRecently;
Player * owner;
Counters * counters;
int typeAsTarget(){return TARGET_CARD;}
int attacker;
MTGCardInstance * banding; // If belongs to a band when attacking
MTGCardInstance * target;
void addType(int type);
//Combat
MTGCardInstance * defenser;
list<MTGCardInstance *>blockers;
int attacker;
int toggleDefenser(MTGCardInstance * opponent);
int moveBlockerInRow(MTGCardInstance * blocker);
int toggleAttacker();
MTGCardInstance * banding; // If belongs to a band when attacking
int canBlock();
int canBlock(MTGCardInstance * opponent);
int canAttack();
int isAttacker();
MTGCardInstance * isDefenser();
int initAttackersDefensers();
MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL);
MTGCardInstance * getNextDefenser(MTGCardInstance * previous=NULL);
int nbOpponents();
int afterDamage();
int has(int ability);
int cleanup();
int reset();
int isAttacker();
MTGCardInstance * isDefenser();
int toggleDefenser(MTGCardInstance * opponent);
int toggleAttacker();
MTGCard * model;
MTGCardInstance();
MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to);
Blockers * getBlockers();
UntapBlockers * getUntapBlockers();
int regenerate();
int triggerRegenerate();
Player * controller();
JQuad * getIcon();
int initAttackersDefensers();
MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL);
int nbOpponents();
~MTGCardInstance();
int bury();
int destroy();

View File

@@ -15,9 +15,9 @@ class MTGGuiPlay: public PlayGuiObjectController {
int offset;
Player * currentPlayer;
MTGCardInstance * cardsGrid[SCREEN_WIDTH/5][SCREEN_HEIGHT/5];
int nb_creatures;
int nb_spells;
int nb_lands;
int nb_creatures[2];
int nb_spells[2];
int nb_lands[2];
int cards_x_limit;
JQuad * phaseIcons[24];

View File

@@ -474,10 +474,59 @@ int AIPlayer::chooseBlockers(){
return 1;
}
int AIPlayer::orderBlockers(){
GameObserver * g = GameObserver::GetInstance();
DamageResolverLayer * drl = g->mLayers->combatLayer();
if (drl->orderingIsNeeded && g->currentPlayer==this){
drl->blockersOrderingDone(); //TODO clever rank of blockers
return 1;
}
return 0;
}
int AIPlayer::combatDamages(){
int result = 0;
GameObserver * gameObs = GameObserver::GetInstance();
int currentGamePhase = gameObs->getCurrentGamePhase();
if (currentGamePhase == Constants::MTG_PHASE_COMBATBLOCKERS) return orderBlockers();
if (currentGamePhase != Constants::MTG_PHASE_COMBATDAMAGE) return 0;
DamageResolverLayer * drl = gameObs->mLayers->combatLayer();
if (drl->currentChoosingPlayer == this){
for (int i = 0; i < drl->mCount; i++){
DamagerDamaged * current = (DamagerDamaged *) drl->mObjects[i];
if (current->damageSelecter == this){
OutputDebugString("YEs, AI IS THE DAMAGE DEALER");
MTGCardInstance * attacker = current->card;
MTGCardInstance * canardEmissaire = *(attacker->blockers.rbegin());
while (canardEmissaire && current->damageToDeal){
drl->clickDamage(canardEmissaire);
}
result = 1;
}
}
}
if (result) return drl->nextPlayer();
return 0;
}
/*
int AIPlayer::combatDamages(){
int result = 0;
GameObserver * gameObs = GameObserver::GetInstance();
int currentGamePhase = gameObs->getCurrentGamePhase();
if (currentGamePhase == Constants::MTG_PHASE_COMBATBLOCKERS) return orderBlockers();
if (currentGamePhase != Constants::MTG_PHASE_COMBATDAMAGE) return 0;
DamageResolverLayer * drl = gameObs->mLayers->combatLayer();
#if defined (WIN32) || defined (LINUX)
@@ -524,6 +573,7 @@ int AIPlayer::combatDamages(){
}
}
}
if (result){
drl->nextPlayer();
}
@@ -531,6 +581,7 @@ int AIPlayer::combatDamages(){
return result;
}
*/
AIStats * AIPlayer::getStats(){
if (!stats){

View File

@@ -1,32 +1,32 @@
#include "../include/config.h"
#include "../include/Blocker.h"
Blocker::Blocker(int id, MTGCardInstance * card):MTGAbility(id, card){
UntapBlocker::UntapBlocker(int id, MTGCardInstance * card):MTGAbility(id, card){
init ( NEW ManaCost());
}
Blocker::Blocker(int id, MTGCardInstance * card, ManaCost * _cost):MTGAbility(id, card){
UntapBlocker::UntapBlocker(int id, MTGCardInstance * card, ManaCost * _cost):MTGAbility(id, card){
init(_cost);
}
Blocker::Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target):MTGAbility(id, card,_target){
UntapBlocker::UntapBlocker(int id, MTGCardInstance * card, MTGCardInstance *_target):MTGAbility(id, card,_target){
init ( NEW ManaCost());
}
Blocker::Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost):MTGAbility(id, card,_target){
UntapBlocker::UntapBlocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost):MTGAbility(id, card,_target){
init(_cost);
}
Blocker::~Blocker(){
UntapBlocker::~UntapBlocker(){
SAFE_DELETE(manaCost);
}
void Blocker::init(ManaCost * _cost){
void UntapBlocker::init(ManaCost * _cost){
currentPhase = -1;
manaCost = _cost;
}
//Default behaviour for blockers : they block the card they're attached to
void Blocker::Update(float dt){
void UntapBlocker::Update(float dt){
game = GameObserver::GetInstance();
int newPhase = game->getCurrentGamePhase();
if (newPhase != currentPhase){
@@ -36,7 +36,7 @@ void Blocker::Update(float dt){
}else{
_target = source;
}
_target->getBlockers()->Add(this);
_target->getUntapBlockers()->Add(this);
#if defined (WIN32) || defined (LINUX)
char buf[4096];
sprintf(buf, "Adding Blocker to %s \n", _target->model->getName());
@@ -46,24 +46,24 @@ void Blocker::Update(float dt){
currentPhase = newPhase;
}
int Blocker::destroy(){
int UntapBlocker::destroy(){
MTGCardInstance * _target;
if (target){
_target = (MTGCardInstance *) target;
}else{
_target = source;
}
_target->getBlockers()->Remove(this);
_target->getUntapBlockers()->Remove(this);
return 1;
}
Blockers::Blockers(){
UntapBlockers::UntapBlockers(){
init();
}
int Blockers::init(){
int UntapBlockers::init(){
cursor = -1;
for (int i=0; i< MAX_BLOCKERS ; i++){
@@ -73,25 +73,25 @@ int Blockers::init(){
return 1;
}
int Blockers::Add (Blocker * ability){
int UntapBlockers::Add (UntapBlocker * ability){
game = GameObserver::GetInstance();
int index = game->mLayers->actionLayer()->getIndexOf(ability);
blockers[index] = 1;
return index;
}
int Blockers::Remove (Blocker * ability){
int UntapBlockers::Remove (UntapBlocker * ability){
game = GameObserver::GetInstance();
int index = game->mLayers->actionLayer()->getIndexOf(ability);
blockers[index] = 0;
return index;
}
int Blockers::rewind(){
int UntapBlockers::rewind(){
cursor = -1;
return 1;
}
Blocker * Blockers::next(){
UntapBlocker * UntapBlockers::next(){
cursor++;
game = GameObserver::GetInstance();
while (blockers[cursor] == 0){
@@ -101,12 +101,12 @@ Blocker * Blockers::next(){
return NULL;
}
}
return (Blocker *) (game->mLayers->actionLayer()->getByIndex(cursor));
return (UntapBlocker *) (game->mLayers->actionLayer()->getByIndex(cursor));
}
int Blockers::isEmpty(){
int UntapBlockers::isEmpty(){
for (int i=0; i< MAX_BLOCKERS ; i++){
if (blockers[i])
return 0;
@@ -114,6 +114,6 @@ int Blockers::isEmpty(){
return 1;
}
Blockers::~Blockers(){
UntapBlockers::~UntapBlockers(){
}

View File

@@ -233,7 +233,8 @@ void CardGui::Update(float dt){
}
if (card->changedZoneRecently){
if (mParticleSys) mParticleSys->Update(dt);
card->changedZoneRecently-= (5 *dt);
card->changedZoneRecently-= (5 *dt);
if (card->changedZoneRecently == 0) card->changedZoneRecently-= dt;//must not become zero atm
if (card->changedZoneRecently < 0){
if (mParticleSys) mParticleSys->Stop();
}

View File

@@ -8,8 +8,8 @@ int ConstraintResolver::untap(GameObserver * game, MTGCardInstance * card){
}
int ok = 1;
ManaCost * untapManaCost = NEW ManaCost();
Blockers * blockers = card->getBlockers();
Blocker * blocker;
UntapBlockers * blockers = card->getUntapBlockers();
UntapBlocker * blocker;
blockers->rewind();
Player * player = game->currentPlayer;
while ((blocker = blockers->next())){

View File

@@ -12,17 +12,22 @@ DamageResolverLayer::DamageResolverLayer(int id, GameObserver * _game):PlayGuiOb
currentSource = NULL;
buttonOk = 0;
currentChoosingPlayer = NULL;
orderingIsNeeded = 0;
}
void DamageResolverLayer::Update(float dt){
int newPhase = game->getCurrentGamePhase();
if (newPhase == Constants::MTG_PHASE_UNTAP){
orderingIsNeeded = 0;
game->blockersSorted = 0;
}
if (newPhase == Constants::MTG_PHASE_COMBATDAMAGE){
if (!game->mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)){
if (newPhase != currentPhase){
init();
init();
}
if (remainingDamageSteps && empty()){
initResolve();
OutputDebugString("Combat Damage STEP\n");
initResolve();
}
}
}else{
@@ -33,6 +38,26 @@ void DamageResolverLayer::Update(float dt){
}
int DamageResolverLayer::autoOrderBlockers(){
resetObjects();
MTGInPlay * attackers = game->currentPlayer->game->inPlay;
MTGCardInstance * attacker = attackers->getNextAttacker(NULL);
while (attacker != NULL){
if (attacker->blockers.size() > 1){
orderingIsNeeded = 1;
Player * p = attacker->controller();
addIfNotExists(attacker, p);
list<MTGCardInstance *>::iterator it;
for (it= attacker->blockers.begin(); it != attacker->blockers.end(); ++it){
addIfNotExists(*it, p);
}
}
attacker = attackers->getNextAttacker(attacker);
}
game->blockersSorted = 1;
return 1 - orderingIsNeeded;
};
Player * DamageResolverLayer::whoSelectsDamagesDealtBy(MTGCardInstance * card){
if (card->controller() == game->currentPlayer){ //Attacker
MTGInPlay * defensers = game->opponent()->game->inPlay;
@@ -75,41 +100,66 @@ int DamageResolverLayer::addAutoDamageToOpponents(MTGCardInstance * card){
}
int DamageResolverLayer::addIfNotExists(MTGCardInstance * card, Player * selecter){
DamagerDamaged * DamageResolverLayer::addIfNotExists(MTGCardInstance * card, Player * selecter){
for (int i = 0; i < mCount; i++){
DamagerDamaged * item = (DamagerDamaged *)mObjects[i];
if (item->card == card) return 0;
if (item->card == card) return item;
}
CardGui * cardg = game->mLayers->playLayer()->getByCard(card);
DamagerDamaged * item = NEW DamagerDamaged(cardg, selecter, mCount == 0);
Add(item);
mCurr = 0;
return item;
}
void DamageResolverLayer::updateAllCoordinates(){
for (int i = 0; i < mCount; i++){
DamagerDamaged * item = (DamagerDamaged *)mObjects[i];
CardGui * cardg = game->mLayers->playLayer()->getByCard(item->card);
item->x = cardg->x;
item->y = cardg->y;
}
}
int DamageResolverLayer::updateCoordinates(MTGCardInstance * card){
DamagerDamaged * item;
for (int i = 0; i < mCount; i++){
item = (DamagerDamaged *)mObjects[i];
if (item->card != card) item = NULL ;
}
if (!item) return 0;
CardGui * cardg = game->mLayers->playLayer()->getByCard(card);
item->x = cardg->x;
item->y = cardg->y;
return 1;
}
//Adds a card and all its opponents to the Damagers' list
int DamageResolverLayer::addDamager(MTGCardInstance * card, Player * selecter){
addIfNotExists(card, selecter);
DamagerDamaged * me = addIfNotExists(card, selecter);
if (card->controller() == game->currentPlayer){ //Attacker
MTGInPlay * defensers = game->opponent()->game->inPlay;
MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card);
while (defenser != NULL){
addIfNotExists(defenser, whoSelectsDamagesDealtBy(defenser));
DamagerDamaged * item = addIfNotExists(defenser, whoSelectsDamagesDealtBy(defenser));
while (!item->hasLethalDamage() && me->dealOneDamage(item)){} //Add default damage to the card...
defenser = defensers->getNextDefenser(defenser, card);
}
}else{ //Defenser
MTGInPlay * attackers = game->currentPlayer->game->inPlay;
MTGCardInstance * attacker = card->isDefenser();
addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker));
DamagerDamaged * item = addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker));
while (!item->hasLethalDamage() && me->dealOneDamage(item)){} //Add default damage to the card...
MTGCardInstance * banding = attacker->banding;
if (banding){
attacker = attackers->getNextAttacker(NULL);
while (attacker != NULL){
if (attacker->banding == banding){
addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker));
}
attacker = attackers->getNextAttacker(attacker);
if (attacker->banding == banding){
item = addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker));
while (!item->hasLethalDamage() && me->dealOneDamage(item)){} //Add default damage to the card...
}
attacker = attackers->getNextAttacker(attacker);
}
}
}
@@ -139,27 +189,23 @@ int DamageResolverLayer::initResolve(){
MTGCardInstance * attacker = attackers->getNextAttacker(NULL);
while (attacker != NULL){
#if defined (WIN32) || defined (LINUX)
sprintf(buf, "attacker : %s \n", attacker->getName());
OutputDebugString(buf);
#endif
if ((!strike && !attacker->has(Constants::FIRSTSTRIKE)) || (strike && attacker->has(Constants::FIRSTSTRIKE)) || attacker->has(Constants::DOUBLESTRIKE)){
Player * selecter = whoSelectsDamagesDealtBy(attacker);
if (!selecter){
addAutoDamageToOpponents(attacker);
if ((!strike && !attacker->has(Constants::FIRSTSTRIKE)) || (strike && attacker->has(Constants::FIRSTSTRIKE)) || attacker->has(Constants::DOUBLESTRIKE)){
OutputDebugString("Attacker Damaging!\n");
if (Player * selecter = whoSelectsDamagesDealtBy(attacker)){
addDamager(attacker, selecter);
}else{
addDamager(attacker, selecter);
addAutoDamageToOpponents(attacker);
}
}
MTGCardInstance * defenser = defensers->getNextDefenser(NULL, attacker);
while (defenser != NULL){
if ((!strike && !defenser->has(Constants::FIRSTSTRIKE)) || (strike && defenser->has(Constants::FIRSTSTRIKE)) || defenser->has(Constants::DOUBLESTRIKE)){
Player * selecterb = whoSelectsDamagesDealtBy(defenser);
if (!selecterb){
addAutoDamageToOpponents(defenser);
}else{
addDamager(defenser, selecterb);
}
if ((!strike && !defenser->has(Constants::FIRSTSTRIKE)) || (strike && defenser->has(Constants::FIRSTSTRIKE)) || defenser->has(Constants::DOUBLESTRIKE)){
OutputDebugString("Blocker Damaging!\n");
if (Player * selecterb = whoSelectsDamagesDealtBy(defenser)){
addDamager(defenser, selecterb);
}else{
addAutoDamageToOpponents(defenser);
}
}
defenser = defensers->getNextDefenser(defenser, attacker);
}
@@ -177,7 +223,7 @@ int DamageResolverLayer::initResolve(){
damageStack = NULL;
modal = remainingDamageSteps;
}else{
if (canStopDealDamages()) currentChoosingPlayer = game->opponent();
//nextPlayer();
}
return 1;
}
@@ -199,22 +245,35 @@ DamagerDamaged * DamageResolverLayer::findByCard(MTGCardInstance * card){
int DamageResolverLayer::canStopDealDamages(){
for (int i = 0; i < mCount ; i ++){
DamagerDamaged * current = (DamagerDamaged *) mObjects[i];
if (current->damageSelecter==currentChoosingPlayer && current->damageToDeal > 0){
MTGCardInstance * card = current->card;
MTGCardInstance * card = current->card;
if (current->damageSelecter==currentChoosingPlayer){
if (current->damageToDeal > 0){
if (card->controller() == game->currentPlayer){ //Attacker
if (card->has(Constants::TRAMPLE)){
MTGInPlay * defensers = game->opponent()->game->inPlay;
MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card);
while (defenser != NULL){
DamagerDamaged * _defenser = findByCard(defenser);
if (!_defenser->hasLethalDamage()) return 0;
defenser = defensers->getNextDefenser(defenser, card);
}
}else{
return 0;
}
}else{ //Defenser
return 0;
}
}
if (card->controller() == game->currentPlayer){ //Attacker
if (card->has(Constants::TRAMPLE)){
MTGInPlay * defensers = game->opponent()->game->inPlay;
MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card);
while (defenser != NULL){
DamagerDamaged * _defenser = findByCard(defenser);
if (!_defenser->hasLethalDamage()) return 0;
defenser = defensers->getNextDefenser(defenser, card);
}
}else{
return 0;
}
}else{ //Defenser
return 0;
//check that blockers have lethal damage
list<MTGCardInstance *>::iterator it;
int found_non_lethal = 0;
for (it= card->blockers.begin(); it != card->blockers.end(); ++it){
MTGCardInstance * c = *it;
DamagerDamaged * defenser = findByCard(c);
if (found_non_lethal && defenser->sumDamages()) return 0;
if (!defenser->hasLethalDamage()) found_non_lethal = 1;
}
}
}
}
@@ -274,44 +333,95 @@ int DamageResolverLayer::isOpponent(DamagerDamaged * a, DamagerDamaged * b){
return 0;
}
void DamageResolverLayer::nextPlayer(){
int DamageResolverLayer::nextPlayer(){
if (!canStopDealDamages()) return 0;
if (currentChoosingPlayer == game->currentPlayer){
currentChoosingPlayer = game->opponent();
if (canStopDealDamages()) resolveDamages();
}else{
resolveDamages();
}
resolveDamages();
return 1;
}
bool DamageResolverLayer::blockersOrderingDone(){
orderingIsNeeded = 0;
game->blockersSorted = 1;
resetObjects();
return true;
}
bool DamageResolverLayer::clickReorderBlocker(MTGCardInstance * blocker){
if (!blocker->defenser) return false;
MTGCardInstance * attacker = blocker->defenser;
attacker->moveBlockerInRow(blocker);
list<MTGCardInstance *>::iterator it;
return true;
}
bool DamageResolverLayer::checkUserInputOrderBlockers(u32 key){
if (PSP_CTRL_CIRCLE == key) {
if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){
DamagerDamaged * current = (DamagerDamaged *) mObjects[mCurr];
MTGCardInstance * blocker = current->card;
return clickReorderBlocker(blocker);
}
return false;
}else if (PSP_CTRL_SQUARE == key){
return blockersOrderingDone();
}else{
return PlayGuiObjectController::CheckUserInput(key);
}
}
bool DamageResolverLayer::clickDamage(MTGCardInstance *c){
DamagerDamaged * current = findByCard(c);
return clickDamage(current);
}
bool DamageResolverLayer::clickDamage(DamagerDamaged * current){
if (!current) return false;
if (!currentSource || !isOpponent(current,currentSource)){
for (int i = 0; i < mCount; i++){
DamagerDamaged * _current = (DamagerDamaged *) mObjects[i];
if (isOpponent(current,_current)){
currentSource = _current;
break;
}
}
}
if (currentSource){
if (currentSource->damageSelecter == currentChoosingPlayer){
if (isOpponent(current,currentSource)){
MTGCardInstance * card = currentSource->card;
list<MTGCardInstance *>::iterator it = card->blockers.begin();
while (it!= card->blockers.end() && *it!=current->card){
DamagerDamaged * item = findByCard(*it);
while (!item->hasLethalDamage() && currentSource->dealOneDamage(item)){} //Add default damage to the card...
it++;
}
if (!currentSource->dealOneDamage(current)){
currentSource->removeDamagesTo(current);
}
}
}
}else{
if (current->damageSelecter == currentChoosingPlayer){
currentSource = current;
}
}
return true;
}
bool DamageResolverLayer::CheckUserInput(u32 key){
if (!mCount) return false;
if (orderingIsNeeded) return checkUserInputOrderBlockers(key);
if (PSP_CTRL_CIRCLE == key){
if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){
DamagerDamaged * current = (DamagerDamaged *) mObjects[mCurr];
if (!currentSource || !isOpponent(current,currentSource)){
for (int i = 0; i < mCount; i++){
DamagerDamaged * _current = (DamagerDamaged *) mObjects[i];
if (isOpponent(current,_current)){
currentSource = _current;
break;
}
}
}
if (currentSource){
if (currentSource->damageSelecter == currentChoosingPlayer){
if (isOpponent(current,currentSource)){
if (!currentSource->dealOneDamage(current)){
currentSource->removeDamagesTo(current);
}
}
}
}else{
if (current->damageSelecter == currentChoosingPlayer){
currentSource = current;
}
}
buttonOk = 0;
if (canStopDealDamages()) buttonOk = 1;
return clickDamage(current);
//buttonOk = 0;
//if (canStopDealDamages()) buttonOk = 1;
}
return true;
}else if (PSP_CTRL_CROSS == key){
@@ -323,11 +433,7 @@ bool DamageResolverLayer::CheckUserInput(u32 key){
return true;
}
}else if (PSP_CTRL_SQUARE == key){
if (canStopDealDamages()){
nextPlayer();
//switch to next player or end of selection
}
return true;
return nextPlayer();
}else{
return PlayGuiObjectController::CheckUserInput(key);
}
@@ -336,15 +442,16 @@ bool DamageResolverLayer::CheckUserInput(u32 key){
void DamageResolverLayer::Render(){
if (!mCount) return;
updateAllCoordinates(); //this is dirty :(
JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MAIN_FONT);
mFont->SetBase(0);
JRenderer * renderer = JRenderer::GetInstance();
renderer->FillRect(0 ,0 , SCREEN_WIDTH , SCREEN_HEIGHT , ARGB(200,0,0,0));
if (currentChoosingPlayer == game->currentPlayer){
mFont->DrawString("Player 1", 0,0);
mFont->DrawString("Attacking Player", 0,0);
}else{
mFont->DrawString("Player 2", 0,0);
mFont->DrawString("Blocking Player", 0,0);
}
if (currentSource){
currentSource->RenderBig(10, 20);
@@ -358,7 +465,8 @@ void DamageResolverLayer::Render(){
}
if (buttonOk){
if (currentPhase == Constants::MTG_PHASE_COMBATDAMAGE && canStopDealDamages()){
mFont->DrawString("Damages Assigned, Click Square to Continue", 250, 5);
}
if (orderingIsNeeded) mFont->DrawString("Order blockers, then Click Square to Continue", 200, 5);
}

View File

@@ -1,7 +1,9 @@
#include "../include/config.h"
#include "../include/DamagerDamaged.h"
/*
Temporary objects that store the damages dealt to/from creatures during the combat phase
*/
DamagerDamaged::DamagerDamaged(CardGui * cardg, Player * _damageSelecter, bool _hasFocus):CardGui(0, cardg->card,cardg->defaultHeight,cardg->x,cardg->y, _hasFocus){
@@ -26,7 +28,7 @@ int DamagerDamaged::sumDamages(){
}
int DamagerDamaged::hasLethalDamage(){
if (sumDamages() >= card->toughness) return 1;
if (sumDamages() >= card->life) return 1;
return 0;
}

View File

@@ -52,6 +52,8 @@ GameObserver::GameObserver(Player * _players[], int _nb_players){
gameOver = NULL;
phaseRing = NEW PhaseRing(_players,_nb_players);
replacementEffects = NEW ReplacementEffects();
blockersSorted = false;
blockersAssigned = 0;
}
void GameObserver::setGamePhaseManager(MTGGamePhase * _phases){
@@ -78,10 +80,20 @@ void GameObserver::nextPlayer(){
currentPlayerId = (currentPlayerId+1)%nbPlayers;
currentPlayer = players[currentPlayerId];
currentActionPlayer = currentPlayer;
blockersSorted = false;
blockersAssigned = 0;
}
void GameObserver::nextGamePhase(){
Phase * cPhaseOld = phaseRing->getCurrentPhase();
if (!blockersSorted && cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS){
blockersAssigned = 1;
if (!mLayers->combatLayer()->autoOrderBlockers()){
OutputDebugString("Player has To choose ordering!");
return;
}
}
phaseRing->forward();
Phase * cPhase = phaseRing->getCurrentPhase();
@@ -140,11 +152,22 @@ int GameObserver::cancelCurrentAction(){
}
void GameObserver::userRequestNextGamePhase(){
OutputDebugString("requesting Next Phase\n");
if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return;
if (getCurrentTargetChooser()) return;
if (mLayers->combatLayer()->remainingDamageSteps) return;
//TODO CHECK POSSIBILITY
if (opponent()->isAI() || GameOptions::GetInstance()->values[GameOptions::phaseInterrupts[currentGamePhase]].getIntValue()){
if (mLayers->combatLayer()->isDisplayed()) return;
Phase * cPhaseOld = phaseRing->getCurrentPhase();
if (!blockersSorted && cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS){
blockersAssigned = 1;
if (!mLayers->combatLayer()->autoOrderBlockers()){
OutputDebugString("Player has To choose ordering!");
return;
}
}
OutputDebugString("Next Phase Accepted\n");
if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS ||
opponent()->isAI() ||
GameOptions::GetInstance()->values[GameOptions::phaseInterrupts[currentGamePhase]].getIntValue()){
mLayers->stackLayer()->AddNextGamePhase();
}else{
nextGamePhase();
@@ -237,7 +260,7 @@ GameObserver::~GameObserver(){
void GameObserver::Update(float dt){
Player * player = currentPlayer;
if (currentGamePhase == Constants::MTG_PHASE_COMBATBLOCKERS){
if (currentGamePhase == Constants::MTG_PHASE_COMBATBLOCKERS && !blockersSorted){
player = opponent();
}else if (currentGamePhase == Constants::MTG_PHASE_COMBATDAMAGE){
DamageResolverLayer * drl = mLayers->combatLayer();

View File

@@ -932,29 +932,29 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
//TODO
}
}else{
if(tc){
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc,doTap));
}else{
if (lordType == PARSER_FOREACH){
game->addObserver(NEW AForeach(id,card,target,lordTargets,lordIncludeSelf,power,toughness));
}else if (lordType == PARSER_ASLONGAS){
game->addObserver(NEW AKirdApe(id,card,lordTargets,lordIncludeSelf,power,toughness));
if(tc){
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc,doTap));
}else{
if (lordType == PARSER_FOREACH){
game->addObserver(NEW AForeach(id,card,target,lordTargets,lordIncludeSelf,power,toughness));
}else if (lordType == PARSER_ASLONGAS){
game->addObserver(NEW AKirdApe(id,card,lordTargets,lordIncludeSelf,power,toughness));
}else{
if (!cost){
if(card->hasType("enchantment")){
game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness));
}else{
if (!cost){
if(card->hasType("enchantment")){
game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness));
}else{
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness));
}
}else{
game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit));
}
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness));
}
}
}else{
game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit));
}
}
result++;
continue;
}
}
result++;
continue;
}
//Mana Producer
found = s.find("add");
@@ -970,43 +970,44 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
if (input->isNull()){
SAFE_DELETE(input);
}
MTGAbility * a = NEW AManaProducer(id, target, output, input,doTap);
ManaCost * FinalOutput = NEW ManaCost();
if (lordType == PARSER_FOREACH){
int multiplier = countCards(lordTargets);
for (int i = 0; i < Constants::MTG_NB_COLORS; i++){
if (output->hasColor(i)){
FinalOutput->add(i,multiplier);
}
}
game->addObserver (NEW AManaProducer(id, target,FinalOutput, input,doTap));
}else{
if (multi){
multi->Add(a);
}else{
game->addObserver(a);
}
}
}else{
MTGAbility * a = NEW AManaProducer(id, target, output, input,doTap);
if (lordType == PARSER_FOREACH){
ManaCost * FinalOutput = NEW ManaCost();
int multiplier = countCards(lordTargets);
for (int i = 0; i < Constants::MTG_NB_COLORS; i++){
if (output->hasColor(i)){
FinalOutput->add(i,multiplier);
}
}
game->addObserver (NEW AManaProducer(id, target,FinalOutput, input,doTap));
}else{
if (multi){
multi->Add(a);
}else{
game->addObserver(a);
}
}
}else{
OutputDebugString ("uh oh\n");
if (lordType == PARSER_FOREACH){
ManaCost * FinalOutput = NEW ManaCost();
int multiplier = countCards(lordTargets);
for (int i = 0; i < Constants::MTG_NB_COLORS; i++){
if (output->hasColor(i)){
FinalOutput->add(i,multiplier);
}
}
card->controller()->getManaPool()->add(FinalOutput);
delete FinalOutput;
}else{
card->controller()->getManaPool()->add(output);
delete output;
}
}
result++;
continue;
}
if (lordType == PARSER_FOREACH){
ManaCost * FinalOutput = NEW ManaCost();
int multiplier = countCards(lordTargets);
for (int i = 0; i < Constants::MTG_NB_COLORS; i++){
if (output->hasColor(i)){
FinalOutput->add(i,multiplier);
}
}
card->controller()->getManaPool()->add(FinalOutput);
delete FinalOutput;
}else{
card->controller()->getManaPool()->add(output);
delete output;
}
}
result++;
continue;
}
//Gain/loose Ability
for (int j = 0; j < Constants::NB_BASIC_ABILITIES; j++){
@@ -2105,7 +2106,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
case 129521: //Dehydratation
// Don't understand why but target automatically untap when cast...
{
game->addObserver(NEW Blocker(_id,card,card->target));
game->addObserver(NEW UntapBlocker(_id,card,card->target));
break;
}
@@ -2245,7 +2246,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
}
if (card->basicAbilities[Constants::DOESNOTUNTAP]){
game->addObserver(NEW Blocker(_id, card));
game->addObserver(NEW UntapBlocker(_id, card));
}
// Tested works the first r10 did not function because of the mistake in the array of the definition

View File

@@ -9,6 +9,8 @@
#include "../include/CardDescriptor.h"
#include "../include/Counters.h"
#include "../include/Subtypes.h"
#include <algorithm>
using namespace std;
MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0){
LOG("==Creating MTGCardInstance==");
@@ -75,7 +77,7 @@ void MTGCardInstance::copy(MTGCardInstance * card){
MTGCardInstance::~MTGCardInstance(){
LOG("==Deleting MTGCardInstance==");
SAFE_DELETE(blockers);
SAFE_DELETE(untapBlockers);
SAFE_DELETE(counters);
SAFE_DELETE(previous);
LOG("==Deleting MTGCardInstance Succesfull==");
@@ -88,7 +90,7 @@ void MTGCardInstance::initMTGCI(){
doDamageTest = 1;
belongs_to=NULL;
tapped = 0;
blockers = NULL;
untapBlockers = NULL;
untapping = 0;
summoningSickness = 0;
target = NULL;
@@ -111,9 +113,9 @@ void MTGCardInstance::addType(int type){
nb_types++;
}
Blockers * MTGCardInstance::getBlockers(){
if (!blockers) blockers = NEW Blockers();
return blockers;
UntapBlockers * MTGCardInstance::getUntapBlockers(){
if (!untapBlockers) untapBlockers = NEW UntapBlockers();
return untapBlockers;
}
int MTGCardInstance::isInPlay(){
@@ -238,6 +240,7 @@ int MTGCardInstance::initAttackersDefensers(){
attacker = 0;
defenser = NULL;
banding = NULL;
blockers.clear();
return 1;
}
@@ -437,6 +440,37 @@ int MTGCardInstance::nbOpponents(){
}
return result;
}
MTGCardInstance * MTGCardInstance::getNextDefenser(MTGCardInstance * previous){
int found_previous = 0;
if (!previous) found_previous = 1;
list<MTGCardInstance *>::iterator it;
for (it= blockers.begin(); it != blockers.end(); ++it){
MTGCardInstance * c = *it;
if (found_previous && c->isInPlay()) return c;
if (c == previous) found_previous = 1;
}
return NULL;
}
int MTGCardInstance::moveBlockerInRow(MTGCardInstance * blocker){
list<MTGCardInstance *>::iterator it1 = find(blockers.begin(), blockers.end(), blocker);
list<MTGCardInstance *>::iterator it2 = it1;
if (it2 != blockers.end()) it2++;
if (it2 == blockers.end()) it2 = blockers.begin();
blockers.splice( it2, blockers, it1 ); // move a before b, invalidates a
char buffer[512];
OutputDebugString("===Outputing blockers\n");
for (it1 = blockers.begin(); it1 != blockers.end(); it1++){
MTGCardInstance * c = *it1;
sprintf(buffer, "%p-", c);
OutputDebugString(buffer);
}
OutputDebugString("\n===End Outputing blockers\n");
return 1;
}
//Returns opponents to this card for this turn. This * should * take into account banding
MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){
GameObserver * game = GameObserver::GetInstance();
@@ -474,7 +508,12 @@ MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){
int MTGCardInstance::toggleDefenser(MTGCardInstance * opponent){
if (canBlock()){
if (canBlock(opponent)){
if (defenser) defenser->blockers.remove(this);
defenser = opponent;
if (defenser){
defenser->blockers.push_back(this);
}
GameObserver::GetInstance()->blockersSorted = false;
return 1;
}
}

View File

@@ -149,10 +149,11 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
}
}
MTGCardInstance * ret = copy;
if (card->isToken){
if (to != g->players[0]->game->inPlay && to != g->players[1]->game->inPlay){
garbage->addCard(copy);
return NULL;
to = garbage;
ret = NULL;
}
}
@@ -162,7 +163,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
WEvent * e = NEW WEventZoneChange(copy, from, to);
g->receiveEvent(e);
delete e;
return copy;
return ret;
}
return card; //Error
}
@@ -331,19 +332,7 @@ int MTGInPlay::nbPartners(MTGCardInstance * attacker){
}
MTGCardInstance * MTGInPlay::getNextDefenser(MTGCardInstance * previous, MTGCardInstance * attacker){
int foundprevious = 0;
if (previous == NULL){
foundprevious = 1;
}
for (int i = 0; i < nb_cards; i ++){
MTGCardInstance * current = cards[i];
if (current == previous){
foundprevious = 1;
}else if (foundprevious && current->isDefenser() == attacker){
return current;
}
}
return NULL;
return attacker->getNextDefenser(previous);
}
MTGCardInstance * MTGInPlay::getNextAttacker(MTGCardInstance * previous){
@@ -366,7 +355,7 @@ void MTGInPlay::untapAll(){
int i;
for (i = 0; i < nb_cards; i ++){
cards[i]->setUntapping();
if (cards[i]->getBlockers()->isEmpty()){
if (cards[i]->getUntapBlockers()->isEmpty()){
#if defined (WIN32) || defined (LINUX)
char buf[4096];
sprintf(buf, "Can untap %s\n", cards[i]->getName());

View File

@@ -91,9 +91,17 @@ void MTGGuiPlay::initCardsDisplay(){
}
}
cards_x_limit = 12;
nb_creatures = 0;
nb_lands = 0;
nb_spells = 0;
for (int i = 0; i < 2; i++){
nb_creatures[i] = 0;
nb_lands[i] = 0;
nb_spells[i] = 0;
}
for (int i = 6; i < mCount; i++){
CardGui * cardg = (CardGui *)mObjects[i];
cardg->x = 0;
cardg->y = 0;
}
}
@@ -111,43 +119,64 @@ void MTGGuiPlay::adjustCardPosition(CardGui * cardg){
}
void MTGGuiPlay::setCardPosition(CardGui * cardg, int player, int playerTurn, int spellMode){
GameObserver * g = GameObserver::GetInstance();
MTGCardInstance * card = cardg->card;
if (!(cardg->x ==0 && cardg->y ==0)) return ;
if (card->target)
return;
if (spellMode && (card->isACreature() || card->hasType("land"))) return;
if (!spellMode && !card->isACreature() && !card->hasType("land")) return;
if (card->isACreature()){
int x_offset = nb_creatures % cards_x_limit;
int y_offset = nb_creatures / cards_x_limit;
int x_offset = nb_creatures[player] % cards_x_limit;
int y_offset = nb_creatures[player] / cards_x_limit;
cardg->x= ZX_MAIN + (Z_CARDWIDTH * x_offset);
cardg->y=ZY_MAIN + ZH_CREATURES + (Z_CARDHEIGHT * y_offset) + 100 * (1-player);
nb_creatures++;
nb_creatures[player]++;
if (playerTurn){
if (card->isAttacker()){
cardg->y=122 + 30 * (1-player);
cardg->y=122 + 30 * (1-player);
//Sets position of opponents as well
if (player == 1){
for (list<MTGCardInstance *>::iterator it= card->blockers.begin(); it !=card->blockers.end() ; ++it){
CardGui * c = getByCard(*it);
if (c) {
setCardPosition(c,1-player,1-playerTurn,spellMode);
adjustCardPosition(c);
}
}
}else{
for (list<MTGCardInstance *>::reverse_iterator it= card->blockers.rbegin(); it !=card->blockers.rend() ; ++it){
CardGui * c = getByCard(*it);
if (c) {
setCardPosition(c,1-player,1-playerTurn,spellMode);
adjustCardPosition(c);
}
}
}
}
}else{
if (card->isDefenser()){
CardGui * targetg = getByCard(card->isDefenser());
if (targetg) cardg->x = targetg->x;
cardg->y=122 + 30 * (1-player);
CardGui * targetg = getByCard(card->isDefenser());
if (targetg) cardg->x = targetg->x;
cardg->y=122 + 30 * (1-player);
}
}
}else if(card->hasType("land")){
int x_offset = nb_lands % cards_x_limit;
int y_offset = nb_lands/ cards_x_limit;
int x_offset = nb_lands[player] % cards_x_limit;
int y_offset = nb_lands[player] / cards_x_limit;
cardg->x=ZX_MAIN + (Z_CARDWIDTH * x_offset);
cardg->y=ZY_MAIN + (Z_CARDHEIGHT * y_offset) + 200 * (1-player);
nb_lands++;
nb_lands[player]++;
}else{
int y_offset = nb_spells % Z_SPELLS_NBCARDS;
int x_offset = nb_spells/ Z_SPELLS_NBCARDS;
int y_offset = nb_spells[player] % Z_SPELLS_NBCARDS;
int x_offset = nb_spells[player] / Z_SPELLS_NBCARDS;
cardg->x=ZX_SPELL - (Z_CARDWIDTH * x_offset);
cardg->y=ZY_SPELL + (Z_CARDHEIGHT * y_offset) + 125 * (1-player);
nb_spells++;
cards_x_limit = 12 - (nb_spells + 2)/ Z_SPELLS_NBCARDS;
nb_spells[player]++;
cards_x_limit = 12 - (nb_spells[player] + 2)/ Z_SPELLS_NBCARDS;
}
adjustCardPosition(cardg);
}
@@ -208,6 +237,7 @@ int MTGGuiPlay::receiveEvent(WEvent *event){
}
if (!ok) return 0;
forceUpdateCards();
updateCards();
return 1;
}
@@ -229,25 +259,27 @@ void MTGGuiPlay::updateCards(){
//This is just so that we display the cards of the current player first, so that blockers are correctly positionned
initCardsDisplay();
for (int j= 0; j < 2; j++){
initCardsDisplay();
if (j != player0Mode){
for (int i =0; i<nb_cards; i++){
CardGui * cardGui = (CardGui *)mObjects[i + offset];
setCardPosition(cardGui, 0, player0Mode, 1);
CardGui * cardGui = (CardGui *)mObjects[i + offset];
setCardPosition(cardGui, 0, player0Mode, 1);
}
for (int i =0; i<nb_cards; i++){
CardGui * cardGui = (CardGui *)mObjects[i + offset];
setCardPosition(cardGui, 0, player0Mode, 0);
CardGui * cardGui = (CardGui *)mObjects[i + offset];
MTGCardInstance * card = cardGui->card;
setCardPosition(cardGui, 0, player0Mode, 0);
}
}else{
for (int i =0; i<opponent_cards; i++){
CardGui * cardGui = (CardGui *)mObjects[nb_cards + i + offset];
setCardPosition(cardGui, 1, !player0Mode,1);
CardGui * cardGui = (CardGui *)mObjects[nb_cards + i + offset];
setCardPosition(cardGui, 1, !player0Mode,1);
}
for (int i =0; i<opponent_cards; i++){
CardGui * cardGui = (CardGui *)mObjects[nb_cards + i + offset];
setCardPosition(cardGui, 1, !player0Mode,0);
CardGui * cardGui = (CardGui *)mObjects[nb_cards + i + offset];
MTGCardInstance * card = cardGui->card;
setCardPosition(cardGui, 1, !player0Mode,0);
}
}
}

View File

@@ -130,7 +130,7 @@ MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){
}
int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
if (currentPhase == Constants::MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting && card->controller() == game->opponent()){
if (currentPhase == Constants::MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting && card->controller() == game->currentlyActing()){
if (card->canBlock()) return 1;
}
return 0;
@@ -166,6 +166,11 @@ ostream& MTGBlockRule::toString(ostream& out) const
return MTGAbility::toString(out) << ")";
}
//
// Attacker chooses blockers order
//
//
// * Momir
//

View File

@@ -3,6 +3,7 @@
#include "../include/MTGAbility.h"
#include "../include/MTGRules.h"
#include "../include/ActionLayer.h"
#include "../include/DamageResolverLayer.h"
#include <string>
using std::string;
@@ -63,6 +64,8 @@ int TestSuiteAI::Act(float dt){
string action = suite->getNextAction();
g->mLayers->stackLayer()->Dump();
DamageResolverLayer * drl = g->mLayers->combatLayer();
OutputDebugString(action.c_str());
OutputDebugString("\n");
@@ -87,7 +90,16 @@ int TestSuiteAI::Act(float dt){
g->userRequestNextGamePhase();
}
else if (action.compare("next")==0){
g->userRequestNextGamePhase();
if (drl->orderingIsNeeded){
drl->blockersOrderingDone();
g->userRequestNextGamePhase();
}else if (drl->mCount){
OutputDebugString("End of combat damage!\n");
drl->nextPlayer();
g->userRequestNextGamePhase();
}else{
g->userRequestNextGamePhase();
}
}else if (action.compare("yes")==0){
g->mLayers->stackLayer()->setIsInterrupting(this);
}else if (action.compare("endinterruption")==0){
@@ -121,7 +133,17 @@ int TestSuiteAI::Act(float dt){
if (card) {
OutputDebugString("Clicking ON: ");
OutputDebugString(card->name.c_str());
g->cardClick(card,card);
if (drl->mCount){
if (drl->orderingIsNeeded){
OutputDebugString(" Ordering Card\n");
drl->clickReorderBlocker(card);
}else{
OutputDebugString(" Damaging Card\n");
drl->clickDamage(card);
}
}else{
g->cardClick(card,card);
}
}
}
}else{