Erwan
- Magic 2010 - blockers ordering - Fixed a memory leak introduced in a previous revision (foreach)
This commit is contained in:
@@ -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
|
||||
|
||||
28
projects/mtg/bin/Res/test/generic/m10_blockers.txt
Normal file
28
projects/mtg/bin/Res/test/generic/m10_blockers.txt
Normal 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]
|
||||
@@ -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();
|
||||
|
||||
@@ -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) << ")";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -28,10 +28,11 @@ class GameObserver{
|
||||
int nbPlayers;
|
||||
int currentPlayerId;
|
||||
int currentRound;
|
||||
|
||||
int blockersAssigned;
|
||||
|
||||
|
||||
public:
|
||||
int blockersSorted;
|
||||
int forceShuffleLibrary[2];
|
||||
int turn;
|
||||
int forceShuffleLibraries();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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(){
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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())){
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user