Erwan
- Magic 2010: Combat Damages don't go on the stack anymore - Comp rules: "goes to graveyard" effects don't go on the stack anymore - Regenerate "fixed" (untested) - Basic "ReplacementEffect" mechanism for damage prevention. Can be extended to other replacement effects with some limits. - TODO: Damages don't go on the stack, the abilities that create them do.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.o objs/GuiPhaseBar.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/TexturesCache.o objs/Token.o objs/Translate.o objs/utils.o objs/WEvent.o
|
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.o objs/GuiPhaseBar.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ReplacementEffects.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/TexturesCache.o objs/Token.o objs/Translate.o objs/utils.o objs/WEvent.o
|
||||||
DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
|
DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
|
||||||
|
|
||||||
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)
|
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)
|
||||||
|
|||||||
@@ -9,16 +9,11 @@ inplay:1335,plains
|
|||||||
1166
|
1166
|
||||||
next
|
next
|
||||||
#blockers
|
#blockers
|
||||||
next
|
|
||||||
no
|
|
||||||
#damage phase
|
|
||||||
no
|
|
||||||
#interrupt the actual damage
|
|
||||||
yes
|
|
||||||
plains
|
plains
|
||||||
1335
|
1335
|
||||||
1166
|
1166
|
||||||
endinterrupt
|
next
|
||||||
|
#damage
|
||||||
next
|
next
|
||||||
#combatend
|
#combatend
|
||||||
[ASSERT]
|
[ASSERT]
|
||||||
|
|||||||
@@ -434,12 +434,8 @@ class ADestroyer:public TargetAbility{
|
|||||||
int resolve(){
|
int resolve(){
|
||||||
MTGCardInstance * _target = tc->getNextCardTarget();
|
MTGCardInstance * _target = tc->getNextCardTarget();
|
||||||
if(_target){
|
if(_target){
|
||||||
if (bury){
|
if (bury) return _target->bury();
|
||||||
_target->controller()->game->putInGraveyard(_target);
|
else return _target->destroy();
|
||||||
}else{
|
|
||||||
game->mLayers->stackLayer()->addPutInGraveyard(_target);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -976,17 +972,46 @@ class ASpellCounterEnchantment:public TargetAbility{
|
|||||||
|
|
||||||
//Circle of Protections
|
//Circle of Protections
|
||||||
class ACircleOfProtection: public TargetAbility{
|
class ACircleOfProtection: public TargetAbility{
|
||||||
|
protected:
|
||||||
|
map<ReplacementEffect*, int> current;
|
||||||
public:
|
public:
|
||||||
ACircleOfProtection(int _id, MTGCardInstance * source, int _color):TargetAbility(_id,source,NEW DamageTargetChooser(source,_color),NEW ManaCost(),0,0){
|
ACircleOfProtection(int _id, MTGCardInstance * source, int _color):TargetAbility(_id,source,NEW SpellOrPermanentTargetChooser(source,_color),NEW ManaCost(),0,0){
|
||||||
cost->add(Constants::MTG_COLOR_ARTIFACT,1);
|
cost->add(Constants::MTG_COLOR_ARTIFACT,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve(){
|
int resolve(){
|
||||||
Damage * damage = tc->getNextDamageTarget();
|
MTGCardInstance * _target = NULL;
|
||||||
if (!damage) return 0;
|
if (! (_target = tc->getNextCardTarget())){
|
||||||
game->mLayers->stackLayer()->Fizzle(damage);
|
Spell * starget = tc->getNextSpellTarget();
|
||||||
|
_target = starget->source;
|
||||||
|
}
|
||||||
|
if (!_target) return 0;
|
||||||
|
REDamagePrevention * re = NEW REDamagePrevention (
|
||||||
|
NEW CardTargetChooser(_target,NULL),
|
||||||
|
NEW PlayerTargetChooser(0,1,source->controller()));
|
||||||
|
current[re] = 1;
|
||||||
|
game->replacementEffects->add(re);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear(){
|
||||||
|
for (map<ReplacementEffect*, int>::iterator it = current.begin(); it!=current.end(); it++){
|
||||||
|
ReplacementEffect* re = (*it).first;
|
||||||
|
game->replacementEffects->remove(re);
|
||||||
|
delete re;
|
||||||
|
}
|
||||||
|
current.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(float dt){
|
||||||
|
if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP) clear();
|
||||||
|
TargetAbility::Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ACircleOfProtection(){
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
virtual ostream& toString(ostream& out) const
|
||||||
{
|
{
|
||||||
out << "ACircleOfProtection ::: (";
|
out << "ACircleOfProtection ::: (";
|
||||||
@@ -1005,16 +1030,6 @@ class AStandardRegenerate:public ActivatedAbility{
|
|||||||
int resolve(){
|
int resolve(){
|
||||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||||
_target->regenerate();
|
_target->regenerate();
|
||||||
PutInGraveyard * action = ((PutInGraveyard *) game->mLayers->stackLayer()->getNext(NULL,ACTION_PUTINGRAVEYARD,NOT_RESOLVED));
|
|
||||||
while(action){
|
|
||||||
#if defined (WIN32) || defined (LINUX)
|
|
||||||
OutputDebugString("Fizzling due to regenerate! \n");
|
|
||||||
#endif
|
|
||||||
if (action->card == _target){
|
|
||||||
game->mLayers->stackLayer()->Fizzle(action);
|
|
||||||
}
|
|
||||||
action = ((PutInGraveyard *) game->mLayers->stackLayer()->getNext(action,ACTION_PUTINGRAVEYARD,NOT_RESOLVED));
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class GameObserver;
|
|||||||
#define DAMAGEABLE_MTGCARDINSTANCE 0
|
#define DAMAGEABLE_MTGCARDINSTANCE 0
|
||||||
#define DAMAGEABLE_PLAYER 1
|
#define DAMAGEABLE_PLAYER 1
|
||||||
|
|
||||||
class Damageable {
|
class Damageable:public Targetable {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "DuelLayers.h"
|
#include "DuelLayers.h"
|
||||||
#include "TargetChooser.h"
|
#include "TargetChooser.h"
|
||||||
#include "PhaseRing.h"
|
#include "PhaseRing.h"
|
||||||
|
#include "ReplacementEffects.h"
|
||||||
|
|
||||||
class MTGGamePhase;
|
class MTGGamePhase;
|
||||||
class MTGAbility;
|
class MTGAbility;
|
||||||
@@ -43,6 +43,7 @@ class GameObserver{
|
|||||||
int oldGamePhase;
|
int oldGamePhase;
|
||||||
TargetChooser * targetChooser;
|
TargetChooser * targetChooser;
|
||||||
DuelLayers * mLayers;
|
DuelLayers * mLayers;
|
||||||
|
ReplacementEffects *replacementEffects;
|
||||||
Player * gameOver;
|
Player * gameOver;
|
||||||
Player * players[2]; //created outside
|
Player * players[2]; //created outside
|
||||||
MTGGamePhase * gamePhaseManager; //Created Outside ?
|
MTGGamePhase * gamePhaseManager; //Created Outside ?
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Counters;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MTGCardInstance: public MTGCard, public Damageable, public Targetable {
|
class MTGCardInstance: public MTGCard, public Damageable {
|
||||||
protected:
|
protected:
|
||||||
int untapping;
|
int untapping;
|
||||||
int nb_damages;
|
int nb_damages;
|
||||||
@@ -37,6 +37,7 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable {
|
|||||||
MTGCardInstance * getNextPartner();
|
MTGCardInstance * getNextPartner();
|
||||||
void initMTGCI();
|
void initMTGCI();
|
||||||
public:
|
public:
|
||||||
|
int regenerateTokens;
|
||||||
bool isToken;
|
bool isToken;
|
||||||
int stillInUse();
|
int stillInUse();
|
||||||
Player * lastController;
|
Player * lastController;
|
||||||
@@ -76,13 +77,16 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable {
|
|||||||
MTGCardInstance();
|
MTGCardInstance();
|
||||||
MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to);
|
MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to);
|
||||||
Blockers * getBlockers();
|
Blockers * getBlockers();
|
||||||
void regenerate();
|
int regenerate();
|
||||||
|
int triggerRegenerate();
|
||||||
Player * controller();
|
Player * controller();
|
||||||
JQuad * getIcon();
|
JQuad * getIcon();
|
||||||
int initAttackersDefensers();
|
int initAttackersDefensers();
|
||||||
MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL);
|
MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL);
|
||||||
int nbOpponents();
|
int nbOpponents();
|
||||||
~MTGCardInstance();
|
~MTGCardInstance();
|
||||||
|
int bury();
|
||||||
|
int destroy();
|
||||||
|
|
||||||
|
|
||||||
int addToToughness(int value);
|
int addToToughness(int value);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
class MTGPlayerCards;
|
class MTGPlayerCards;
|
||||||
class MTGInPlay;
|
class MTGInPlay;
|
||||||
|
|
||||||
class Player: public Damageable, public Targetable{
|
class Player: public Damageable{
|
||||||
protected:
|
protected:
|
||||||
ManaCost * manaPool;
|
ManaCost * manaPool;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _REPLACEMENT_EFFECTS_H_
|
||||||
|
#define _REPLACEMENT_EFFECTS_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
using namespace std;
|
||||||
|
#include "WEvent.h"
|
||||||
|
|
||||||
|
class TargetChooser;
|
||||||
|
|
||||||
|
class ReplacementEffect {
|
||||||
|
public:
|
||||||
|
virtual WEvent * replace (WEvent * e) {return e;};
|
||||||
|
virtual ~ReplacementEffect(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
class REDamagePrevention: public ReplacementEffect {
|
||||||
|
protected:
|
||||||
|
TargetChooser * tcSource;
|
||||||
|
TargetChooser * tcTarget;
|
||||||
|
int damage;
|
||||||
|
bool oneShot;
|
||||||
|
public:
|
||||||
|
REDamagePrevention(TargetChooser *_tcSource = NULL,TargetChooser *_tcTarget = NULL, int _damage = -1, bool _oneShot = true);
|
||||||
|
WEvent * replace (WEvent *e);
|
||||||
|
~REDamagePrevention();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReplacementEffects {
|
||||||
|
protected:
|
||||||
|
list<ReplacementEffect *>modifiers;
|
||||||
|
public:
|
||||||
|
ReplacementEffects();
|
||||||
|
WEvent * replace(WEvent *e);
|
||||||
|
int add(ReplacementEffect * re);
|
||||||
|
int remove (ReplacementEffect * re);
|
||||||
|
~ReplacementEffects();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -52,9 +52,19 @@ class TargetChooserFactory{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CardTargetChooser:public TargetChooser {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MTGCardInstance * validTarget;
|
||||||
|
public:
|
||||||
|
CardTargetChooser(MTGCardInstance * _card, MTGCardInstance * source);
|
||||||
|
virtual int canTarget(Targetable * target );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TargetZoneChooser:public TargetChooser{
|
class TargetZoneChooser:public TargetChooser{
|
||||||
public:
|
public:
|
||||||
MTGGameZone * zones[6];
|
MTGGameZone * zones[10];
|
||||||
int nbzones;
|
int nbzones;
|
||||||
int init(MTGGameZone ** _zones, int _nbzones);
|
int init(MTGGameZone ** _zones, int _nbzones);
|
||||||
int targetsZone(MTGGameZone * z);
|
int targetsZone(MTGGameZone * z);
|
||||||
@@ -83,8 +93,10 @@ class DamageableTargetChooser:public CreatureTargetChooser{
|
|||||||
|
|
||||||
|
|
||||||
class PlayerTargetChooser:public TargetChooser{
|
class PlayerTargetChooser:public TargetChooser{
|
||||||
|
protected:
|
||||||
|
Player * p; //In Case we can only target a specific player
|
||||||
public:
|
public:
|
||||||
PlayerTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1):TargetChooser(card, _maxtargets){};
|
PlayerTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1, Player *_p = NULL);
|
||||||
virtual int canTarget(Targetable * target);
|
virtual int canTarget(Targetable * target);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,17 @@ int Damage::resolve(){
|
|||||||
_target->doDamageTest = 1;
|
_target->doDamageTest = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int a = target->dealDamage(damage);
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
|
WEvent * e = NEW WEventDamage(this);
|
||||||
|
e = g->replacementEffects->replace(e);
|
||||||
|
|
||||||
//Send Damage event to listeners
|
int a = 0;
|
||||||
WEventDamage * e = NEW WEventDamage(this);
|
if (damage) a = target->dealDamage(damage);
|
||||||
GameObserver::GetInstance()->receiveEvent(e);
|
|
||||||
delete e;
|
//Send (Damage/Replaced effect) event to listeners
|
||||||
|
|
||||||
|
g->receiveEvent(e);
|
||||||
|
SAFE_DELETE(e);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ int DamageResolverLayer::initResolve(){
|
|||||||
if (empty()){
|
if (empty()){
|
||||||
if (!damageStack->empty()){
|
if (!damageStack->empty()){
|
||||||
game->mLayers->stackLayer()->addAction(damageStack);
|
game->mLayers->stackLayer()->addAction(damageStack);
|
||||||
|
game->mLayers->stackLayer()->resolve(); //Wagic 2010
|
||||||
}else{
|
}else{
|
||||||
SAFE_DELETE(damageStack);
|
SAFE_DELETE(damageStack);
|
||||||
}
|
}
|
||||||
@@ -246,6 +247,7 @@ int DamageResolverLayer::resolveDamages(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
game->mLayers->stackLayer()->addAction(damageStack);
|
game->mLayers->stackLayer()->addAction(damageStack);
|
||||||
|
game->mLayers->stackLayer()->resolve(); //Wagic 2010
|
||||||
remainingDamageSteps--;
|
remainingDamageSteps--;
|
||||||
resetObjects();
|
resetObjects();
|
||||||
damageStack = NULL;
|
damageStack = NULL;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ GameObserver::GameObserver(Player * _players[], int _nb_players){
|
|||||||
reaction = 0;
|
reaction = 0;
|
||||||
gameOver = NULL;
|
gameOver = NULL;
|
||||||
phaseRing = NEW PhaseRing(_players,_nb_players);
|
phaseRing = NEW PhaseRing(_players,_nb_players);
|
||||||
|
replacementEffects = NEW ReplacementEffects();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObserver::setGamePhaseManager(MTGGamePhase * _phases){
|
void GameObserver::setGamePhaseManager(MTGGamePhase * _phases){
|
||||||
@@ -229,6 +230,7 @@ GameObserver::~GameObserver(){
|
|||||||
SAFE_DELETE(targetChooser);
|
SAFE_DELETE(targetChooser);
|
||||||
SAFE_DELETE(mLayers);
|
SAFE_DELETE(mLayers);
|
||||||
SAFE_DELETE(phaseRing);
|
SAFE_DELETE(phaseRing);
|
||||||
|
SAFE_DELETE(replacementEffects);
|
||||||
LOG("==GameObserver Destroyed==");
|
LOG("==GameObserver Destroyed==");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -442,6 +444,7 @@ void GameObserver::untapPhase(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int GameObserver::receiveEvent(WEvent * e){
|
int GameObserver::receiveEvent(WEvent * e){
|
||||||
|
if (!e) return 0;
|
||||||
return mLayers->receiveEvent(e);
|
return mLayers->receiveEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,14 +37,12 @@ int AbilityFactory::destroyAllInPlay(TargetChooser * tc, int bury){
|
|||||||
tc->source = NULL; // This is to prevent protection from... as objects that destroy all do not actually target
|
tc->source = NULL; // This is to prevent protection from... as objects that destroy all do not actually target
|
||||||
GameObserver * game = GameObserver::GetInstance();
|
GameObserver * game = GameObserver::GetInstance();
|
||||||
for (int i = 0; i < 2 ; i++){
|
for (int i = 0; i < 2 ; i++){
|
||||||
for (int j = game->players[i]->game->inPlay->nb_cards-1; j >=0 ; j--){
|
Player * p = game->players[i];
|
||||||
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
|
for (int j = p->game->inPlay->nb_cards-1; j >=0 ; j--){
|
||||||
|
MTGCardInstance * current = p->game->inPlay->cards[j];
|
||||||
if (tc->canTarget(current)){
|
if (tc->canTarget(current)){
|
||||||
if (bury){
|
if (bury) current->bury();
|
||||||
game->players[i]->game->putInGraveyard(current);
|
else current->destroy();
|
||||||
}else{
|
|
||||||
game->mLayers->stackLayer()->addPutInGraveyard(current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -546,7 +544,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
if (tc){
|
if (tc){
|
||||||
game->addObserver(NEW ABurier(id, card,tc));
|
game->addObserver(NEW ABurier(id, card,tc));
|
||||||
}else{
|
}else{
|
||||||
target->controller()->game->putInGraveyard(target);
|
target->bury();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -584,7 +582,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
if (tc){
|
if (tc){
|
||||||
game->addObserver(NEW ADestroyer(id, card,tc,0,cost));
|
game->addObserver(NEW ADestroyer(id, card,tc,0,cost));
|
||||||
}else{
|
}else{
|
||||||
game->mLayers->stackLayer()->addPutInGraveyard(target);
|
target->destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result++;
|
result++;
|
||||||
@@ -1605,19 +1603,19 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
int _x = x;
|
int _x = x;
|
||||||
MTGCardInstance * target = spell->getNextCardTarget();
|
MTGCardInstance * target = spell->getNextCardTarget();
|
||||||
while(target && _x){
|
while(target && _x){
|
||||||
game->mLayers->stackLayer()->addPutInGraveyard(target);
|
target->destroy();
|
||||||
_x--;
|
_x--;
|
||||||
target = spell->getNextCardTarget(target);
|
target = spell->getNextCardTarget(target);
|
||||||
}
|
}
|
||||||
x-=_x;
|
x-=_x;
|
||||||
for (int i = 0; i < 2 ; i++){
|
for (int i = 0; i < 2 ; i++){
|
||||||
game->mLayers->stackLayer()->addDamage(card, game->players[i], x);
|
game->mLayers->stackLayer()->addDamage(card, game->players[i], x);
|
||||||
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
|
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
|
||||||
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
|
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
|
||||||
if (current->isACreature()){
|
if (current->isACreature()){
|
||||||
game->mLayers->stackLayer()->addDamage(card, current, x);
|
game->mLayers->stackLayer()->addDamage(card, current, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ void MTGCardInstance::initMTGCI(){
|
|||||||
previous = NULL;
|
previous = NULL;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
lastController = NULL;
|
lastController = NULL;
|
||||||
|
regenerateTokens = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -128,13 +129,20 @@ int MTGCardInstance::afterDamage(){
|
|||||||
doDamageTest = 0;
|
doDamageTest = 0;
|
||||||
if (!isACreature()) return 0;
|
if (!isACreature()) return 0;
|
||||||
if (life <=0 && isInPlay()){
|
if (life <=0 && isInPlay()){
|
||||||
GameObserver * game = GameObserver::GetInstance();
|
return destroy();
|
||||||
game->mLayers->stackLayer()->addPutInGraveyard(this);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MTGCardInstance::bury(){
|
||||||
|
Player * p = controller();
|
||||||
|
p->game->putInZone(this,p->game->inPlay,owner->game->graveyard);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int MTGCardInstance::destroy(){
|
||||||
|
if (!triggerRegenerate()) return bury();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
MTGGameZone * MTGCardInstance::getCurrentZone(){
|
MTGGameZone * MTGCardInstance::getCurrentZone(){
|
||||||
GameObserver * game = GameObserver::GetInstance();
|
GameObserver * game = GameObserver::GetInstance();
|
||||||
@@ -194,10 +202,17 @@ void MTGCardInstance::resetAllDamage(){
|
|||||||
nb_damages = 0;
|
nb_damages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTGCardInstance::regenerate(){
|
int MTGCardInstance::regenerate(){
|
||||||
|
return ++regenerateTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MTGCardInstance::triggerRegenerate(){
|
||||||
|
if (! regenerateTokens) return 0;
|
||||||
|
regenerateTokens--;
|
||||||
tapped = 1;
|
tapped = 1;
|
||||||
life = toughness;
|
life = toughness;
|
||||||
initAttackersDefensers();
|
initAttackersDefensers();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,6 +232,7 @@ int MTGCardInstance::cleanup(){
|
|||||||
if (previous && !previous->stillInUse()){
|
if (previous && !previous->stillInUse()){
|
||||||
SAFE_DELETE(previous);
|
SAFE_DELETE(previous);
|
||||||
}
|
}
|
||||||
|
regenerateTokens = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/ReplacementEffects.h"
|
||||||
|
#include "../include/MTGCardInstance.h"
|
||||||
|
#include "../include/TargetChooser.h"
|
||||||
|
#include "../include/Damage.h"
|
||||||
|
|
||||||
|
|
||||||
|
REDamagePrevention::REDamagePrevention(TargetChooser *_tcSource, TargetChooser *_tcTarget,int _damage, bool _oneShot):damage(_damage), tcSource(_tcSource), tcTarget(_tcTarget), oneShot(_oneShot){
|
||||||
|
}
|
||||||
|
|
||||||
|
WEvent * REDamagePrevention::replace (WEvent *event){
|
||||||
|
if (!event) return event;
|
||||||
|
if (!damage) return event;
|
||||||
|
WEventDamage * e = dynamic_cast<WEventDamage*>(event);
|
||||||
|
if (!e) return event;
|
||||||
|
Damage *d = e->damage;
|
||||||
|
if ((!tcSource || tcSource->canTarget(d->source)) &&
|
||||||
|
(!tcTarget || tcTarget->canTarget(d->target))
|
||||||
|
){
|
||||||
|
if (damage == -1){
|
||||||
|
d->damage = 0;
|
||||||
|
delete event;
|
||||||
|
if (oneShot) damage = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (damage >= d->damage){
|
||||||
|
damage-= d->damage;
|
||||||
|
d->damage = 0;
|
||||||
|
delete event;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
d->damage -= damage;
|
||||||
|
damage = 0;
|
||||||
|
delete event;
|
||||||
|
WEventDamage* newEvent = NEW WEventDamage(d);
|
||||||
|
return newEvent;
|
||||||
|
}
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
REDamagePrevention::~REDamagePrevention(){
|
||||||
|
SAFE_DELETE(tcSource);
|
||||||
|
SAFE_DELETE(tcTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplacementEffects::ReplacementEffects(){}
|
||||||
|
|
||||||
|
WEvent * ReplacementEffects::replace(WEvent *e){
|
||||||
|
list<ReplacementEffect *>::iterator it;
|
||||||
|
|
||||||
|
for ( it=modifiers.begin() ; it != modifiers.end(); it++ ){
|
||||||
|
ReplacementEffect *re = *it;
|
||||||
|
WEvent * newEvent = re->replace(e);
|
||||||
|
if (!newEvent) return NULL;
|
||||||
|
if (newEvent != e) return replace(newEvent);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReplacementEffects::add(ReplacementEffect * re){
|
||||||
|
modifiers.push_back(re);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReplacementEffects::remove (ReplacementEffect *re){
|
||||||
|
modifiers.remove(re);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplacementEffects::~ReplacementEffects(){
|
||||||
|
list<ReplacementEffect *>::iterator it;
|
||||||
|
for ( it=modifiers.begin() ; it != modifiers.end(); it++ ){
|
||||||
|
ReplacementEffect *re = *it;
|
||||||
|
delete(re);
|
||||||
|
}
|
||||||
|
modifiers.clear();
|
||||||
|
}
|
||||||
@@ -330,7 +330,21 @@ int TargetChooser::targetListSet(){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
a specific Card
|
||||||
|
**/
|
||||||
|
CardTargetChooser::CardTargetChooser(MTGCardInstance * _card, MTGCardInstance * source):TargetChooser(source){
|
||||||
|
validTarget = _card;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CardTargetChooser::canTarget(Targetable * target ){
|
||||||
|
if (!TargetChooser::canTarget(target)) return 0;
|
||||||
|
if (target->typeAsTarget() == TARGET_CARD){
|
||||||
|
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||||
|
if (card == validTarget) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Choose anything that has a given list of types
|
Choose anything that has a given list of types
|
||||||
@@ -522,9 +536,15 @@ int TargetZoneChooser::targetsZone(MTGGameZone * z){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Player Target */
|
/* Player Target */
|
||||||
|
|
||||||
|
PlayerTargetChooser::PlayerTargetChooser(MTGCardInstance * card, int _maxtargets, Player *_p):TargetChooser(card, _maxtargets){
|
||||||
|
p = _p;
|
||||||
|
}
|
||||||
|
|
||||||
int PlayerTargetChooser::canTarget(Targetable * target){
|
int PlayerTargetChooser::canTarget(Targetable * target){
|
||||||
if (target->typeAsTarget() == TARGET_PLAYER){
|
if (target->typeAsTarget() == TARGET_PLAYER){
|
||||||
return 1;
|
Player * _target = (Player *) target;
|
||||||
|
if (!p || p == _target) return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,6 +372,10 @@
|
|||||||
RelativePath=".\src\GuiLayers.cpp"
|
RelativePath=".\src\GuiLayers.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\GuiPhaseBar.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\Logger.cpp"
|
RelativePath=".\src\Logger.cpp"
|
||||||
>
|
>
|
||||||
@@ -456,6 +460,10 @@
|
|||||||
RelativePath=".\src\PriceList.cpp"
|
RelativePath=".\src\PriceList.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\ReplacementEffects.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\ShopItem.cpp"
|
RelativePath=".\src\ShopItem.cpp"
|
||||||
>
|
>
|
||||||
@@ -673,6 +681,10 @@
|
|||||||
RelativePath=".\include\GuiLayers.h"
|
RelativePath=".\include\GuiLayers.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\GuiPhaseBar.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Logger.h"
|
RelativePath=".\include\Logger.h"
|
||||||
>
|
>
|
||||||
@@ -761,6 +773,10 @@
|
|||||||
RelativePath=".\include\PriceList.h"
|
RelativePath=".\include\PriceList.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\ReplacementEffects.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\ShopItem.h"
|
RelativePath=".\include\ShopItem.h"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user