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:
@@ -434,12 +434,8 @@ class ADestroyer:public TargetAbility{
|
||||
int resolve(){
|
||||
MTGCardInstance * _target = tc->getNextCardTarget();
|
||||
if(_target){
|
||||
if (bury){
|
||||
_target->controller()->game->putInGraveyard(_target);
|
||||
}else{
|
||||
game->mLayers->stackLayer()->addPutInGraveyard(_target);
|
||||
}
|
||||
return 1;
|
||||
if (bury) return _target->bury();
|
||||
else return _target->destroy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -976,17 +972,46 @@ class ASpellCounterEnchantment:public TargetAbility{
|
||||
|
||||
//Circle of Protections
|
||||
class ACircleOfProtection: public TargetAbility{
|
||||
protected:
|
||||
map<ReplacementEffect*, int> current;
|
||||
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);
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
Damage * damage = tc->getNextDamageTarget();
|
||||
if (!damage) return 0;
|
||||
game->mLayers->stackLayer()->Fizzle(damage);
|
||||
MTGCardInstance * _target = NULL;
|
||||
if (! (_target = tc->getNextCardTarget())){
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
out << "ACircleOfProtection ::: (";
|
||||
@@ -1005,16 +1030,6 @@ class AStandardRegenerate:public ActivatedAbility{
|
||||
int resolve(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||
_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class GameObserver;
|
||||
#define DAMAGEABLE_MTGCARDINSTANCE 0
|
||||
#define DAMAGEABLE_PLAYER 1
|
||||
|
||||
class Damageable {
|
||||
class Damageable:public Targetable {
|
||||
protected:
|
||||
|
||||
public:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "DuelLayers.h"
|
||||
#include "TargetChooser.h"
|
||||
#include "PhaseRing.h"
|
||||
|
||||
#include "ReplacementEffects.h"
|
||||
|
||||
class MTGGamePhase;
|
||||
class MTGAbility;
|
||||
@@ -43,6 +43,7 @@ class GameObserver{
|
||||
int oldGamePhase;
|
||||
TargetChooser * targetChooser;
|
||||
DuelLayers * mLayers;
|
||||
ReplacementEffects *replacementEffects;
|
||||
Player * gameOver;
|
||||
Player * players[2]; //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:
|
||||
int untapping;
|
||||
int nb_damages;
|
||||
@@ -37,6 +37,7 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable {
|
||||
MTGCardInstance * getNextPartner();
|
||||
void initMTGCI();
|
||||
public:
|
||||
int regenerateTokens;
|
||||
bool isToken;
|
||||
int stillInUse();
|
||||
Player * lastController;
|
||||
@@ -76,13 +77,16 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable {
|
||||
MTGCardInstance();
|
||||
MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to);
|
||||
Blockers * getBlockers();
|
||||
void regenerate();
|
||||
int regenerate();
|
||||
int triggerRegenerate();
|
||||
Player * controller();
|
||||
JQuad * getIcon();
|
||||
int initAttackersDefensers();
|
||||
MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL);
|
||||
int nbOpponents();
|
||||
~MTGCardInstance();
|
||||
int bury();
|
||||
int destroy();
|
||||
|
||||
|
||||
int addToToughness(int value);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
class MTGPlayerCards;
|
||||
class MTGInPlay;
|
||||
|
||||
class Player: public Damageable, public Targetable{
|
||||
class Player: public Damageable{
|
||||
protected:
|
||||
ManaCost * manaPool;
|
||||
|
||||
|
||||
39
projects/mtg/include/ReplacementEffects.h
Normal file
39
projects/mtg/include/ReplacementEffects.h
Normal file
@@ -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{
|
||||
public:
|
||||
MTGGameZone * zones[6];
|
||||
MTGGameZone * zones[10];
|
||||
int nbzones;
|
||||
int init(MTGGameZone ** _zones, int _nbzones);
|
||||
int targetsZone(MTGGameZone * z);
|
||||
@@ -83,8 +93,10 @@ class DamageableTargetChooser:public CreatureTargetChooser{
|
||||
|
||||
|
||||
class PlayerTargetChooser:public TargetChooser{
|
||||
protected:
|
||||
Player * p; //In Case we can only target a specific player
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user