- Removed "isClone" flag. This flag was error prone. The "core" classes now have decent copy constructors, and ideally long term we should create copy constructors for the abilities that have additional pointers in them.

-- The test suite passes but this is a big change. I might have introduced some memory leaks or bugs. I might have fixed some bugs, too
This commit is contained in:
wagic.the.homebrew
2011-07-27 14:31:27 +00:00
parent a26125ee4c
commit ef5e011e23
14 changed files with 520 additions and 610 deletions
+1 -1
View File
@@ -22,7 +22,6 @@ class ActionElement: public JGuiObject
{ {
protected: protected:
int activeState; int activeState;
int isClone;
public: public:
TargetChooser * tc; TargetChooser * tc;
int currentPhase; int currentPhase;
@@ -48,6 +47,7 @@ public:
} }
; ;
ActionElement(int id); ActionElement(int id);
ActionElement(const ActionElement& copyFromMe);
virtual ~ActionElement(); virtual ~ActionElement();
virtual int isReactingToTargetClick(Targetable * card); virtual int isReactingToTargetClick(Targetable * card);
virtual int reactToTargetClick(Targetable * card); virtual int reactToTargetClick(Targetable * card);
+75 -191
View File
@@ -313,9 +313,7 @@ public:
TrCardAddedToZone * clone() const TrCardAddedToZone * clone() const
{ {
TrCardAddedToZone * a = NEW TrCardAddedToZone(*this); return NEW TrCardAddedToZone(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -357,9 +355,7 @@ public:
TrCardTapped * clone() const TrCardTapped * clone() const
{ {
TrCardTapped * a = NEW TrCardTapped(*this); return NEW TrCardTapped(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -401,9 +397,7 @@ public:
TrCardTappedformana * clone() const TrCardTappedformana * clone() const
{ {
TrCardTappedformana * a = NEW TrCardTappedformana(*this); return NEW TrCardTappedformana(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -538,9 +532,7 @@ public:
TrCombatTrigger * clone() const TrCombatTrigger * clone() const
{ {
TrCombatTrigger * a = NEW TrCombatTrigger(*this); return NEW TrCombatTrigger(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -579,9 +571,7 @@ public:
TrcardDrawn * clone() const TrcardDrawn * clone() const
{ {
TrcardDrawn * a = NEW TrcardDrawn(*this); return NEW TrcardDrawn(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -620,9 +610,7 @@ public:
TrCardSacrificed * clone() const TrCardSacrificed * clone() const
{ {
TrCardSacrificed * a = NEW TrCardSacrificed(*this); return NEW TrCardSacrificed(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -658,9 +646,7 @@ public:
} }
TrCardDiscarded * clone() const TrCardDiscarded * clone() const
{ {
TrCardDiscarded * a = NEW TrCardDiscarded(*this); return NEW TrCardDiscarded(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -718,9 +704,7 @@ public:
TrDamaged * clone() const TrDamaged * clone() const
{ {
TrDamaged * a = NEW TrDamaged(*this); return NEW TrDamaged(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -770,9 +754,7 @@ public:
TrLifeGained * clone() const TrLifeGained * clone() const
{ {
TrLifeGained * a = NEW TrLifeGained(*this); return NEW TrLifeGained(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -823,9 +805,7 @@ public:
TrVampired * clone() const TrVampired * clone() const
{ {
TrVampired * a = NEW TrVampired(*this); return NEW TrVampired(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -869,9 +849,7 @@ public:
TrTargeted * clone() const TrTargeted * clone() const
{ {
TrTargeted * a = NEW TrTargeted(*this); return NEW TrTargeted(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1184,9 +1162,7 @@ public:
ACycle * clone() const ACycle * clone() const
{ {
ACycle * a = NEW ACycle(*this); return NEW ACycle(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1226,9 +1202,7 @@ public:
ANinja * clone() const ANinja * clone() const
{ {
ANinja * a = NEW ANinja(*this); return NEW ANinja(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1260,9 +1234,7 @@ public:
ACombatRemoval * clone() const ACombatRemoval * clone() const
{ {
ACombatRemoval * a = NEW ACombatRemoval(*this); return NEW ACombatRemoval(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1393,9 +1365,7 @@ public:
ABasicAbilityModifier * clone() const ABasicAbilityModifier * clone() const
{ {
ABasicAbilityModifier * a = NEW ABasicAbilityModifier(*this); return NEW ABasicAbilityModifier(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1445,9 +1415,7 @@ public:
AInstantBasicAbilityModifierUntilEOT * clone() const AInstantBasicAbilityModifierUntilEOT * clone() const
{ {
AInstantBasicAbilityModifierUntilEOT * a = NEW AInstantBasicAbilityModifierUntilEOT(*this); return NEW AInstantBasicAbilityModifierUntilEOT(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1494,13 +1462,12 @@ public:
ABasicAbilityAuraModifierUntilEOT * clone() const ABasicAbilityAuraModifierUntilEOT * clone() const
{ {
ABasicAbilityAuraModifierUntilEOT * a = NEW ABasicAbilityAuraModifierUntilEOT(*this); ABasicAbilityAuraModifierUntilEOT * a = NEW ABasicAbilityAuraModifierUntilEOT(*this);
a->isClone = 1; a->ability = ability->clone();
return a; return a;
} }
~ABasicAbilityAuraModifierUntilEOT() ~ABasicAbilityAuraModifierUntilEOT()
{ {
if (!isClone)
SAFE_DELETE(ability); SAFE_DELETE(ability);
} }
}; };
@@ -1565,9 +1532,7 @@ public:
ASpellCastLife * clone() const ASpellCastLife * clone() const
{ {
ASpellCastLife * a = NEW ASpellCastLife(*this); return NEW ASpellCastLife(*this);
a->isClone = 1;
return a;
} }
~ASpellCastLife() ~ASpellCastLife()
@@ -1615,9 +1580,7 @@ public:
AUnBlocker * clone() const AUnBlocker * clone() const
{ {
AUnBlocker * a = NEW AUnBlocker(*this); return NEW AUnBlocker(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1657,7 +1620,6 @@ public:
{ {
AProtectionFrom * a = NEW AProtectionFrom(*this); AProtectionFrom * a = NEW AProtectionFrom(*this);
a->fromTc = fromTc->clone(); a->fromTc = fromTc->clone();
a->isClone = 1;
return a; return a;
} }
@@ -1696,7 +1658,6 @@ public:
{ {
ACantBeTargetFrom * a = NEW ACantBeTargetFrom(*this); ACantBeTargetFrom * a = NEW ACantBeTargetFrom(*this);
a->fromTc = fromTc->clone(); a->fromTc = fromTc->clone();
a->isClone = 1;
return a; return a;
} }
@@ -1734,7 +1695,6 @@ public:
{ {
ACantBeBlockedBy * a = NEW ACantBeBlockedBy(*this); ACantBeBlockedBy * a = NEW ACantBeBlockedBy(*this);
a->fromTc = fromTc->clone(); a->fromTc = fromTc->clone();
a->isClone = 1;
return a; return a;
} }
@@ -1806,7 +1766,6 @@ public:
{ {
APowerToughnessModifier * a = NEW APowerToughnessModifier(*this); APowerToughnessModifier * a = NEW APowerToughnessModifier(*this);
a->wppt = NEW WParsedPT(*(a->wppt)); a->wppt = NEW WParsedPT(*(a->wppt));
a->isClone = 1;
return a; return a;
} }
@@ -1847,7 +1806,6 @@ public:
{ {
GenericInstantAbility * a = NEW GenericInstantAbility(*this); GenericInstantAbility * a = NEW GenericInstantAbility(*this);
a->ability = ability->clone(); a->ability = ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -1866,7 +1824,7 @@ public:
ACircleOfProtection(int _id, MTGCardInstance * source, int _color) : ACircleOfProtection(int _id, MTGCardInstance * source, int _color) :
TargetAbility(_id, source, NEW SpellOrPermanentTargetChooser(source, _color), NEW ManaCost(), 0) TargetAbility(_id, source, NEW SpellOrPermanentTargetChooser(source, _color), NEW ManaCost(), 0)
{ {
cost->add(Constants::MTG_COLOR_ARTIFACT, 1); getCost()->add(Constants::MTG_COLOR_ARTIFACT, 1);
tc->targetter = NULL; //Circle of Protection doesn't use the word "source" tc->targetter = NULL; //Circle of Protection doesn't use the word "source"
} }
@@ -1915,9 +1873,7 @@ public:
} }
ACircleOfProtection * clone() const ACircleOfProtection * clone() const
{ {
ACircleOfProtection * a = NEW ACircleOfProtection(*this); return NEW ACircleOfProtection(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1952,9 +1908,7 @@ public:
} }
AStandardRegenerate * clone() const AStandardRegenerate * clone() const
{ {
AStandardRegenerate * a = NEW AStandardRegenerate(*this); return NEW AStandardRegenerate(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -1996,9 +1950,7 @@ public:
} }
ARegularLifeModifierAura * clone() const ARegularLifeModifierAura * clone() const
{ {
ARegularLifeModifierAura * a = NEW ARegularLifeModifierAura(*this); return NEW ARegularLifeModifierAura(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -2063,9 +2015,7 @@ public:
AExalted * clone() const AExalted * clone() const
{ {
AExalted * a = NEW AExalted(*this); return NEW AExalted(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -2216,8 +2166,7 @@ public:
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
~AAsLongAs() ~AAsLongAs()
{ {
if (!isClone) SAFE_DELETE(ability);
SAFE_DELETE(ability);
} }
const char * getMenuText() const char * getMenuText()
@@ -2235,7 +2184,7 @@ public:
AAsLongAs * clone() const AAsLongAs * clone() const
{ {
AAsLongAs * a = NEW AAsLongAs(*this); AAsLongAs * a = NEW AAsLongAs(*this);
a->isClone = 1; a->ability = ability->clone();
return a; return a;
} }
}; };
@@ -2340,7 +2289,6 @@ public:
~ALord() ~ALord()
{ {
if (!isClone)
SAFE_DELETE(ability); SAFE_DELETE(ability);
} }
@@ -2356,7 +2304,7 @@ public:
ALord * clone() const ALord * clone() const
{ {
ALord * a = NEW ALord(*this); ALord * a = NEW ALord(*this);
a->isClone = 1; a->ability = ability->clone();
return a; return a;
} }
}; };
@@ -2449,14 +2397,13 @@ public:
} }
~ATeach() ~ATeach()
{ {
if (!isClone)
SAFE_DELETE(ability); SAFE_DELETE(ability);
} }
ATeach * clone() const ATeach * clone() const
{ {
ATeach * a = NEW ATeach(*this); ATeach * a = NEW ATeach(*this);
a->isClone = 1; a->ability = ability->clone();
return a; return a;
} }
@@ -2552,9 +2499,7 @@ public:
AEquip * clone() const AEquip * clone() const
{ {
AEquip * a = NEW AEquip(*this); return NEW AEquip(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -2781,7 +2726,6 @@ public:
{ {
ATokenCreator * a = NEW ATokenCreator(*this); ATokenCreator * a = NEW ATokenCreator(*this);
a->multiplier = NEW WParsedInt(*(multiplier)); a->multiplier = NEW WParsedInt(*(multiplier));
a->isClone = 1;
return a; return a;
} }
@@ -2859,7 +2803,7 @@ public:
AForeach * clone() const AForeach * clone() const
{ {
AForeach * a = NEW AForeach(*this); AForeach * a = NEW AForeach(*this);
a->isClone = 1; a->ability = ability->clone();
return a; return a;
} }
@@ -2874,7 +2818,6 @@ public:
~AForeach() ~AForeach()
{ {
if (!isClone)
SAFE_DELETE(ability); SAFE_DELETE(ability);
} }
@@ -2953,15 +2896,15 @@ public:
~AThis() ~AThis()
{ {
if (!isClone)
SAFE_DELETE(ability); SAFE_DELETE(ability);
SAFE_DELETE(td); SAFE_DELETE(td);
} }
AThis * clone() const AThis * clone() const
{ {
AThis * a = NEW AThis(*this); AThis * a = NEW AThis(*this);
a->isClone = 1; a->ability = ability->clone();
a->td = td->clone();
return a; return a;
} }
}; };
@@ -3048,11 +2991,9 @@ public:
~AThisForEach() ~AThisForEach()
{ {
if (!isClone) SAFE_DELETE(ability);
{ SAFE_DELETE(td);
SAFE_DELETE(ability);
SAFE_DELETE(td);
}
if (abilities.size()) if (abilities.size())
{ {
removeAbilityFromGame(); removeAbilityFromGame();
@@ -3066,8 +3007,9 @@ public:
AThisForEach * clone() const AThisForEach * clone() const
{ {
AThisForEach * a = NEW AThisForEach(*this); AThisForEach * a = NEW AThisForEach(*this);
a->isClone = 1; a->ability = ability->clone();
a->td = td->clone();
return a; return a;
} }
}; };
@@ -3157,9 +3099,7 @@ public:
TADamager * clone() const TADamager * clone() const
{ {
TADamager * a = NEW TADamager(*this); return NEW TADamager(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -3343,9 +3283,7 @@ public:
} }
ASwapPT * clone() const ASwapPT * clone() const
{ {
ASwapPT * a = NEW ASwapPT(*this); return NEW ASwapPT(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -3413,9 +3351,7 @@ public:
} }
ALifeZoneLink * clone() const ALifeZoneLink * clone() const
{ {
ALifeZoneLink * a = NEW ALifeZoneLink(*this); return NEW ALifeZoneLink(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -3457,9 +3393,7 @@ public:
} }
AStrongLandLinkCreature * clone() const AStrongLandLinkCreature * clone() const
{ {
AStrongLandLinkCreature * a = NEW AStrongLandLinkCreature(*this); return NEW AStrongLandLinkCreature(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -3495,9 +3429,7 @@ public:
} }
AControlStealAura * clone() const AControlStealAura * clone() const
{ {
AControlStealAura * a = NEW AControlStealAura(*this); return NEW AControlStealAura(*this);
a->isClone = 1;
return a;
} }
}; };
//bloodthirst ability------------------------------------------ //bloodthirst ability------------------------------------------
@@ -3526,9 +3458,7 @@ public:
ABloodThirst * clone() const ABloodThirst * clone() const
{ {
ABloodThirst * a = NEW ABloodThirst(*this); return NEW ABloodThirst(*this);
a->isClone = 1;
return a;
} }
~ABloodThirst() ~ABloodThirst()
@@ -3820,8 +3750,8 @@ public:
AAladdinsLamp(int id, MTGCardInstance * card) : AAladdinsLamp(int id, MTGCardInstance * card) :
TargetAbility(id, card) TargetAbility(id, card)
{ {
cost = NEW ManaCost(); setCost(NEW ManaCost(), true);
cost->x(); getCost()->x();
cd = CardDisplay(1, game, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, NULL); cd = CardDisplay(1, game, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, NULL);
int zones[] = { MTGGameZone::MY_LIBRARY }; int zones[] = { MTGGameZone::MY_LIBRARY };
tc = NEW TargetZoneChooser(zones, 1, source); tc = NEW TargetZoneChooser(zones, 1, source);
@@ -3837,7 +3767,7 @@ public:
{ {
cd.resetObjects(); cd.resetObjects();
int wished = game->currentlyActing()->getManaPool()->getConvertedCost(); int wished = game->currentlyActing()->getManaPool()->getConvertedCost();
game->currentlyActing()->getManaPool()->pay(cost); game->currentlyActing()->getManaPool()->pay(getCost());
nbcards = 0; nbcards = 0;
MTGGameZone * library = game->currentlyActing()->game->library; MTGGameZone * library = game->currentlyActing()->game->library;
while (nbcards < wished) while (nbcards < wished)
@@ -3887,9 +3817,7 @@ public:
} }
AAladdinsLamp * clone() const AAladdinsLamp * clone() const
{ {
AAladdinsLamp * a = NEW AAladdinsLamp(*this); return NEW AAladdinsLamp(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -3951,9 +3879,7 @@ public:
} }
AArmageddonClock * clone() const AArmageddonClock * clone() const
{ {
AArmageddonClock * a = NEW AArmageddonClock(*this); return NEW AArmageddonClock(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4049,9 +3975,7 @@ public:
} }
AConservator * clone() const AConservator * clone() const
{ {
AConservator * a = NEW AConservator(*this); return NEW AConservator(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4064,7 +3988,7 @@ public:
ActivatedAbility(_id, source, 0, 1) ActivatedAbility(_id, source, 0, 1)
{ {
int8_t _cost[] = { Constants::MTG_COLOR_WHITE, 2 }; int8_t _cost[] = { Constants::MTG_COLOR_WHITE, 2 };
cost = NEW ManaCost(_cost, 1); setCost(NEW ManaCost(_cost, 1), true);
target = _target; target = _target;
usedThisTurn = 0; usedThisTurn = 0;
} }
@@ -4100,9 +4024,7 @@ public:
} }
AFarmstead * clone() const AFarmstead * clone() const
{ {
AFarmstead * a = NEW AFarmstead(*this); return NEW AFarmstead(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4162,9 +4084,7 @@ public:
} }
AKjeldoranFrostbeast * clone() const AKjeldoranFrostbeast * clone() const
{ {
AKjeldoranFrostbeast * a = NEW AKjeldoranFrostbeast(*this); return NEW AKjeldoranFrostbeast(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4205,9 +4125,7 @@ public:
} }
AAnimateDead * clone() const AAnimateDead * clone() const
{ {
AAnimateDead * a = NEW AAnimateDead(*this); return NEW AAnimateDead(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4256,9 +4174,7 @@ public:
AErgRaiders * clone() const AErgRaiders * clone() const
{ {
AErgRaiders * a = NEW AErgRaiders(*this); return NEW AErgRaiders(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4325,9 +4241,7 @@ public:
} }
AFastbond * clone() const AFastbond * clone() const
{ {
AFastbond * a = NEW AFastbond(*this); return NEW AFastbond(*this);
a->isClone = 1;
return a;
} }
~AFastbond() ~AFastbond()
@@ -4343,7 +4257,7 @@ public:
AJandorsRing(int _id, MTGCardInstance * _source) : AJandorsRing(int _id, MTGCardInstance * _source) :
ActivatedAbility(_id, _source, NEW ManaCost()) ActivatedAbility(_id, _source, NEW ManaCost())
{ {
cost->add(Constants::MTG_COLOR_ARTIFACT, 2); getCost()->add(Constants::MTG_COLOR_ARTIFACT, 2);
} }
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL) int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL)
@@ -4366,9 +4280,7 @@ public:
} }
AJandorsRing * clone() const AJandorsRing * clone() const
{ {
AJandorsRing * a = NEW AJandorsRing(*this); return NEW AJandorsRing(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4442,9 +4354,7 @@ public:
AKudzu * clone() const AKudzu * clone() const
{ {
AKudzu * a = NEW AKudzu(*this); return NEW AKudzu(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4513,9 +4423,7 @@ public:
} }
APowerLeak * clone() const APowerLeak * clone() const
{ {
APowerLeak * a = NEW APowerLeak(*this); return NEW APowerLeak(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4548,9 +4456,7 @@ public:
} }
ASacrifice * clone() const ASacrifice * clone() const
{ {
ASacrifice * a = NEW ASacrifice(*this); return NEW ASacrifice(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4575,9 +4481,7 @@ public:
} }
AEarthbind * clone() const AEarthbind * clone() const
{ {
AEarthbind * a = NEW AEarthbind(*this); return NEW AEarthbind(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4607,9 +4511,7 @@ public:
} }
AFireball * clone() const AFireball * clone() const
{ {
AFireball * a = NEW AFireball(*this); return NEW AFireball(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4677,9 +4579,7 @@ public:
} }
AIslandSanctuary * clone() const AIslandSanctuary * clone() const
{ {
AIslandSanctuary * a = NEW AIslandSanctuary(*this); return NEW AIslandSanctuary(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4692,7 +4592,7 @@ public:
ActivatedAbility(_id, card, NEW ManaCost(), 0) ActivatedAbility(_id, card, NEW ManaCost(), 0)
{ {
paidThisTurn = 1; paidThisTurn = 1;
cost->add(Constants::MTG_COLOR_BLUE, 1); getCost()->add(Constants::MTG_COLOR_BLUE, 1);
} }
void Update(float dt) void Update(float dt)
@@ -4748,9 +4648,7 @@ public:
} }
AStasis * clone() const AStasis * clone() const
{ {
AStasis * a = NEW AStasis(*this); return NEW AStasis(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4800,9 +4698,7 @@ public:
} }
ABasilik * clone() const ABasilik * clone() const
{ {
ABasilik * a = NEW ABasilik(*this); return NEW ABasilik(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4912,9 +4808,7 @@ public:
AMinionofLeshrac * clone() const AMinionofLeshrac * clone() const
{ {
AMinionofLeshrac * a = NEW AMinionofLeshrac(*this); return NEW AMinionofLeshrac(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -4958,9 +4852,7 @@ public:
ARampageAbility * clone() const ARampageAbility * clone() const
{ {
ARampageAbility * a = NEW ARampageAbility(*this); return NEW ARampageAbility(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -5009,9 +4901,7 @@ public:
AFlankerAbility * clone() const AFlankerAbility * clone() const
{ {
AFlankerAbility * a = NEW AFlankerAbility(*this); return NEW AFlankerAbility(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -5066,9 +4956,7 @@ public:
ABushidoAbility * clone() const ABushidoAbility * clone() const
{ {
ABushidoAbility * a = NEW ABushidoAbility(*this); return NEW ABushidoAbility(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -5101,9 +4989,7 @@ public:
} }
ASpiritLinkAbility * clone() const ASpiritLinkAbility * clone() const
{ {
ASpiritLinkAbility * a = NEW ASpiritLinkAbility(*this); return NEW ASpiritLinkAbility(*this);
a->isClone = 1;
return a;
} }
}; };
@@ -5143,9 +5029,7 @@ public:
AInstantControlSteal * clone() const AInstantControlSteal * clone() const
{ {
AInstantControlSteal * a = NEW AInstantControlSteal(*this); return NEW AInstantControlSteal(*this);
a->isClone = 1;
return a;
} }
}; };
+9 -4
View File
@@ -42,6 +42,8 @@ using std::map;
class MTGAbility : public ActionElement class MTGAbility : public ActionElement
{ {
private:
ManaCost* mCost;
protected: protected:
char menuText[50]; char menuText[50];
@@ -104,14 +106,10 @@ public:
}; };
int parseCastRestrictions(MTGCardInstance* card, Player* player, string restrictions, string otherRestrictions);
int allowedToCast(MTGCardInstance* card, Player* player);
int allowedToAltCast(MTGCardInstance* card, Player* player);
bool oneShot; bool oneShot;
int forceDestroy; int forceDestroy;
int forcedAlive; int forcedAlive;
bool canBeInterrupted; bool canBeInterrupted;
ManaCost* cost;
ManaCost* alternative; ManaCost* alternative;
ManaCost* BuyBack; ManaCost* BuyBack;
ManaCost* FlashBack; ManaCost* FlashBack;
@@ -124,10 +122,17 @@ public:
int naType; int naType;
int abilitygranted; int abilitygranted;
MTGCardInstance * source; MTGCardInstance * source;
int parseCastRestrictions(MTGCardInstance* card, Player* player, string restrictions, string otherRestrictions);
int allowedToCast(MTGCardInstance* card, Player* player);
int allowedToAltCast(MTGCardInstance* card, Player* player);
MTGAbility(int id, MTGCardInstance * card); MTGAbility(int id, MTGCardInstance * card);
MTGAbility(int id, MTGCardInstance * _source, Targetable * _target); MTGAbility(int id, MTGCardInstance * _source, Targetable * _target);
MTGAbility(const MTGAbility& copyFromMe);
virtual int testDestroy(); virtual int testDestroy();
virtual ~MTGAbility(); virtual ~MTGAbility();
ManaCost * getCost() {return mCost;};
void setCost(ManaCost * cost, bool forceDelete = 0);
virtual void Render() virtual void Render()
{ {
+158 -141
View File
@@ -1,142 +1,159 @@
/* /*
Filter-like system for determining if a card meats certain criteria, for this and thisforeach autos Filter-like system for determining if a card meets certain criteria, for this and thisforeach autos
*/ */
#ifndef _THISDESCRIPTOR_H_ #ifndef _THISDESCRIPTOR_H_
#define _THISDESCRIPTOR_H_ #define _THISDESCRIPTOR_H_
#include "Counters.h" #include "Counters.h"
#include "MTGGameZones.h" #include "MTGGameZones.h"
#include "MTGCardInstance.h" #include "MTGCardInstance.h"
#include "CardDescriptor.h" #include "CardDescriptor.h"
class ThisDescriptor{ class ThisDescriptor{
public: public:
int comparisonMode; int comparisonMode;
int comparisonCriterion; int comparisonCriterion;
virtual int match(MTGCardInstance * card) = 0; virtual int match(MTGCardInstance * card) = 0;
int matchValue(int value); int matchValue(int value);
virtual ~ThisDescriptor(); virtual ~ThisDescriptor();
}; virtual ThisDescriptor * clone() const = 0;
};
class ThisDescriptorFactory{
public: class ThisDescriptorFactory{
ThisDescriptor * createThisDescriptor(string s); public:
}; ThisDescriptor * createThisDescriptor(string s);
};
class ThisCounter:public ThisDescriptor{
public: class ThisCounter:public ThisDescriptor{
Counter * counter; public:
virtual int match(MTGCardInstance * card); Counter * counter;
virtual int match(MTGCardInstance * card);
ThisCounter(Counter * _counter);
ThisCounter(int power, int toughness, int nb, const char * name); ThisCounter(Counter * _counter);
~ThisCounter(); ThisCounter(int power, int toughness, int nb, const char * name);
}; ~ThisCounter();
ThisCounter * clone() const;
class ThisCounterAny:public ThisDescriptor{ };
public:
virtual int match(MTGCardInstance *card); class ThisCounterAny:public ThisDescriptor{
public:
ThisCounterAny(int nb); virtual int match(MTGCardInstance *card);
};
ThisCounterAny(int nb);
class ThisControllerlife:public ThisDescriptor{ ThisCounterAny * clone() const;
public: };
virtual int match(MTGCardInstance * card);
class ThisControllerlife:public ThisDescriptor{
ThisControllerlife(int life); public:
}; virtual int match(MTGCardInstance * card);
class ThisOpponentlife:public ThisDescriptor{ ThisControllerlife(int life);
public: ThisControllerlife * clone() const;
virtual int match(MTGCardInstance * card); };
ThisOpponentlife(int olife); class ThisOpponentlife:public ThisDescriptor{
}; public:
virtual int match(MTGCardInstance * card);
class ThisEquip:public ThisDescriptor{
public: ThisOpponentlife(int olife);
virtual int match(MTGCardInstance * card); ThisOpponentlife * clone() const;
};
ThisEquip(int equipment);
}; class ThisEquip:public ThisDescriptor{
public:
class ThisAuras:public ThisDescriptor{ virtual int match(MTGCardInstance * card);
public:
virtual int match(MTGCardInstance * card); ThisEquip(int equipment);
ThisEquip * clone() const;
ThisAuras(int auras); };
};
class ThisAuras:public ThisDescriptor{
class ThisOpponentDamageAmount:public ThisDescriptor{ public:
public: virtual int match(MTGCardInstance * card);
virtual int match(MTGCardInstance * card);
ThisAuras(int auras);
ThisOpponentDamageAmount(int damagecount); ThisAuras * clone() const;
}; };
class ThisUntapped:public ThisDescriptor{ class ThisOpponentDamageAmount:public ThisDescriptor{
public: public:
virtual int match(MTGCardInstance * card); virtual int match(MTGCardInstance * card);
ThisUntapped(int untapped); ThisOpponentDamageAmount(int damagecount);
}; ThisOpponentDamageAmount * clone() const;
};
class ThisTapped:public ThisDescriptor{
public: class ThisUntapped:public ThisDescriptor{
virtual int match(MTGCardInstance * card); public:
virtual int match(MTGCardInstance * card);
ThisTapped(int tapped);
}; ThisUntapped(int untapped);
ThisUntapped * clone() const;
};
class ThisAttacked:public ThisDescriptor{
public: class ThisTapped:public ThisDescriptor{
virtual int match(MTGCardInstance * card); public:
virtual int match(MTGCardInstance * card);
ThisAttacked(int attack);
}; ThisTapped(int tapped);
ThisTapped * clone() const;
class ThisBlocked:public ThisDescriptor{ };
public:
virtual int match(MTGCardInstance * card);
class ThisAttacked:public ThisDescriptor{
ThisBlocked(int block); public:
}; virtual int match(MTGCardInstance * card);
class ThisNotBlocked:public ThisDescriptor{ ThisAttacked(int attack);
public: ThisAttacked * clone() const;
virtual int match(MTGCardInstance * card); };
ThisNotBlocked(int unblocked); class ThisBlocked:public ThisDescriptor{
}; public:
virtual int match(MTGCardInstance * card);
class ThisDamaged:public ThisDescriptor{
public: ThisBlocked(int block);
virtual int match(MTGCardInstance * card); ThisBlocked * clone() const;
};
ThisDamaged(int wasDealtDamage);
}; class ThisNotBlocked:public ThisDescriptor{
public:
class ThisPower:public ThisDescriptor{ virtual int match(MTGCardInstance * card);
public:
virtual int match(MTGCardInstance * card); ThisNotBlocked(int unblocked);
ThisNotBlocked * clone() const;
ThisPower(int power); };
};
class ThisDamaged:public ThisDescriptor{
class ThisToughness:public ThisDescriptor{ public:
public: virtual int match(MTGCardInstance * card);
virtual int match(MTGCardInstance * card);
ThisDamaged(int wasDealtDamage);
ThisToughness(int toughness); ThisDamaged * clone() const;
}; };
class ThisX:public ThisDescriptor{ class ThisPower:public ThisDescriptor{
public: public:
virtual int match(MTGCardInstance * card); virtual int match(MTGCardInstance * card);
ThisX(int x);
}; ThisPower(int power);
ThisPower * clone() const;
};
class ThisToughness:public ThisDescriptor{
public:
virtual int match(MTGCardInstance * card);
ThisToughness(int toughness);
ThisToughness * clone() const;
};
class ThisX:public ThisDescriptor{
public:
virtual int match(MTGCardInstance * card);
ThisX(int x);
ThisX * clone() const;
};
#endif #endif
+3 -3
View File
@@ -130,7 +130,7 @@ RankingContainer AIHints::findActions(AIHint * hint)
for (int j = 0; j < mPlayer->game->inPlay->nb_cards; j++) for (int j = 0; j < mPlayer->game->inPlay->nb_cards; j++)
{ {
MTGCardInstance * card = mPlayer->game->inPlay->cards[j]; MTGCardInstance * card = mPlayer->game->inPlay->cards[j];
if (a->isReactingToClick(card, a->cost)) if (a->isReactingToClick(card, a->getCost()))
{ {
mPlayer->createAbilityTargets(a, card, ranking); //TODO make that function static? mPlayer->createAbilityTargets(a, card, ranking); //TODO make that function static?
break; //For performance... ? break; //For performance... ?
@@ -177,7 +177,7 @@ string AIHints::constraintsNotFulfilled(AIAction * action, AIHint * hint, ManaCo
return "not supported"; return "not supported";
//dummy test: would the ability work if we were sure to fulfill its mana requirements? //dummy test: would the ability work if we were sure to fulfill its mana requirements?
if (!a->isReactingToClick(card, a->cost)) if (!a->isReactingToClick(card, a->getCost()))
{ {
DebugTrace("This shouldn't happen, this AIAction doesn't seem like a good choice"); DebugTrace("This shouldn't happen, this AIAction doesn't seem like a good choice");
return "not supported"; return "not supported";
@@ -186,7 +186,7 @@ string AIHints::constraintsNotFulfilled(AIAction * action, AIHint * hint, ManaCo
if (!a->isReactingToClick(card, potentialMana)) if (!a->isReactingToClick(card, potentialMana))
{ {
//Not enough Mana, try to find which mana we should get in priority //Not enough Mana, try to find which mana we should get in priority
ManaCost * diff = potentialMana->Diff(a->cost); ManaCost * diff = potentialMana->Diff(a->getCost());
for (int i = 0; i < Constants::MTG_NB_COLORS; i++) for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
{ {
if(diff->getCost(i) < 0) if(diff->getCost(i) < 0)
+2 -1
View File
@@ -18,7 +18,8 @@ AIMomirPlayer::AIMomirPlayer(string file, string fileSmall, string avatarFile, M
int AIMomirPlayer::getEfficiency(AIAction * action) int AIMomirPlayer::getEfficiency(AIAction * action)
{ {
MTGAbility * ability = action->ability; MTGAbility * ability = action->ability;
if (ability->cost && !(ability->cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet ManaCost * cost = ability->getCost();
if (cost && !(cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet
int efficiency = AIPlayerBaka::getEfficiency(action); int efficiency = AIPlayerBaka::getEfficiency(action);
GameObserver * g = GameObserver::GetInstance(); GameObserver * g = GameObserver::GetInstance();
+6 -5
View File
@@ -242,7 +242,7 @@ int AIPlayer::CanHandleCost(ManaCost * cost)
int AIPlayer::canHandleCost(MTGAbility * ability) int AIPlayer::canHandleCost(MTGAbility * ability)
{ {
return CanHandleCost(ability->cost); return CanHandleCost(ability->getCost());
} }
// In this function, target represents the target of the currentAIAction object, while _target is the target of the ability of this AIAction object // In this function, target represents the target of the currentAIAction object, while _target is the target of the ability of this AIAction object
@@ -753,9 +753,10 @@ int AIAction::getEfficiency()
if (p->game->hand->nb_cards == 0) if (p->game->hand->nb_cards == 0)
efficiency = (int) ((float) efficiency * 1.3); //increase chance of using ability if hand is empty efficiency = (int) ((float) efficiency * 1.3); //increase chance of using ability if hand is empty
if (ability->cost) ManaCost * cost = ability->getCost();
if (cost)
{ {
ExtraCosts * ec = ability->cost->extraCosts; ExtraCosts * ec = cost->extraCosts;
if (ec) if (ec)
{ {
for(unsigned int i = 0; i < ec->costs.size();i++) for(unsigned int i = 0; i < ec->costs.size();i++)
@@ -816,7 +817,7 @@ int AIPlayer::selectHintAbility()
if (!clickstream.size()) if (!clickstream.size())
{ {
DebugTrace("AIPlayer:Using Activated ability"); DebugTrace("AIPlayer:Using Activated ability");
if (tapLandsForMana(action->ability->cost, action->click)) if (tapLandsForMana(action->ability->getCost(), action->click))
{ {
clickstream.push(action); clickstream.push(action);
SAFE_DELETE(totalPotentialMana); SAFE_DELETE(totalPotentialMana);
@@ -890,7 +891,7 @@ int AIPlayer::selectAbility()
if (!clickstream.size()) if (!clickstream.size())
{ {
DebugTrace("AIPlayer:Using Activated ability"); DebugTrace("AIPlayer:Using Activated ability");
if (tapLandsForMana(action.ability->cost, action.click)) if (tapLandsForMana(action.ability->getCost(), action.click))
clickstream.push(NEW AIAction(action)); clickstream.push(NEW AIAction(action));
} }
} }
+12 -5
View File
@@ -14,15 +14,22 @@ ActionElement::ActionElement(int id) :
currentPhase = -1; currentPhase = -1;
newPhase = -1; newPhase = -1;
tc = NULL; tc = NULL;
isClone = 0; }
ActionElement::ActionElement(const ActionElement& a): JGuiObject(a)
{
activeState = a.activeState;
tc = a.tc ? a.tc->clone() : NULL;
currentPhase = a.currentPhase;
newPhase = a.newPhase;
modal = a.modal;
waitingForAnswer = a.waitingForAnswer;
} }
ActionElement::~ActionElement() ActionElement::~ActionElement()
{ {
if (!isClone) SAFE_DELETE(tc);
{
SAFE_DELETE(tc);
}
} }
int ActionElement::getActivity() int ActionElement::getActivity()
+60 -137
View File
@@ -16,10 +16,14 @@ GenericActivatedAbility::GenericActivatedAbility(string newName,int _id, MTGCard
int GenericActivatedAbility::resolve() int GenericActivatedAbility::resolve()
{ {
ManaCost * diff = abilityCost->Diff(cost); //Note: I've seen a similar block in some other MTGAbility, can this be refactored .
source->X = diff->hasX(); source->X = 0;
SAFE_DELETE(diff); if (abilityCost)
//SAFE_DELETE(abilityCost); this line has been reported as a bug. removing it doesn't seem to break anything, although I didn't get any error in the test suite by leaving it either, so... leaving it for now as a comment, in case. {
ManaCost * diff = abilityCost->Diff(getCost());
source->X = diff->hasX();
SAFE_DELETE(diff);
}
ability->target = target; //may have been updated... ability->target = target; //may have been updated...
if (ability) if (ability)
return ability->resolve(); return ability->resolve();
@@ -60,8 +64,8 @@ int GenericActivatedAbility::testDestroy()
GenericActivatedAbility * GenericActivatedAbility::clone() const GenericActivatedAbility * GenericActivatedAbility::clone() const
{ {
GenericActivatedAbility * a = NEW GenericActivatedAbility(*this); GenericActivatedAbility * a = NEW GenericActivatedAbility(*this);
a->cost = NEW ManaCost(); //a->getCost() = NEW ManaCost();
a->cost->copy(cost); //a->getCost()->copy(cost);
a->ability = ability->clone(); a->ability = ability->clone();
return a; return a;
} }
@@ -95,9 +99,7 @@ const char * AAAlterPoison::getMenuText()
AAAlterPoison * AAAlterPoison::clone() const AAAlterPoison * AAAlterPoison::clone() const
{ {
AAAlterPoison * a = NEW AAAlterPoison(*this); return NEW AAAlterPoison(*this);
a->isClone = 1;
return a;
} }
AAAlterPoison::~AAAlterPoison() AAAlterPoison::~AAAlterPoison()
@@ -129,9 +131,7 @@ const char * AADamagePrevent::getMenuText()
AADamagePrevent * AADamagePrevent::clone() const AADamagePrevent * AADamagePrevent::clone() const
{ {
AADamagePrevent * a = NEW AADamagePrevent(*this); return NEW AADamagePrevent(*this);
a->isClone = 1;
return a;
} }
AADamagePrevent::~AADamagePrevent() AADamagePrevent::~AADamagePrevent()
@@ -172,9 +172,7 @@ AADamager::AADamager(int _id, MTGCardInstance * _source, Targetable * _target, s
AADamager * AADamager::clone() const AADamager * AADamager::clone() const
{ {
AADamager * a = NEW AADamager(*this); return NEW AADamager(*this);
a->isClone = 1;
return a;
} }
@@ -217,9 +215,7 @@ const char * AADepleter::getMenuText()
AADepleter * AADepleter::clone() const AADepleter * AADepleter::clone() const
{ {
AADepleter * a = NEW AADepleter(*this); return NEW AADepleter(*this);
a->isClone = 1;
return a;
} }
//AACopier //AACopier
@@ -247,9 +243,7 @@ const char * AACopier::getMenuText()
AACopier * AACopier::clone() const AACopier * AACopier::clone() const
{ {
AACopier * a = NEW AACopier(*this); return NEW AACopier(*this);
a->isClone = 1;
return a;
} }
//phaser //phaser
@@ -282,9 +276,7 @@ const char * AAPhaseOut::getMenuText()
AAPhaseOut * AAPhaseOut::clone() const AAPhaseOut * AAPhaseOut::clone() const
{ {
AAPhaseOut * a = NEW AAPhaseOut(*this); return NEW AAPhaseOut(*this);
a->isClone = 1;
return a;
} }
//Counters //Counters
@@ -378,9 +370,7 @@ const char* AACounter::getMenuText()
AACounter * AACounter::clone() const AACounter * AACounter::clone() const
{ {
AACounter * a = NEW AACounter(*this); return NEW AACounter(*this);
a->isClone = 1;
return a;
} }
//Counters //Counters
@@ -460,9 +450,7 @@ const char* AARemoveAllCounter::getMenuText()
AARemoveAllCounter * AARemoveAllCounter::clone() const AARemoveAllCounter * AARemoveAllCounter::clone() const
{ {
AARemoveAllCounter * a = NEW AARemoveAllCounter(*this); return NEW AARemoveAllCounter(*this);
a->isClone = 1;
return a;
} }
//Reset Damage on creatures //Reset Damage on creatures
@@ -485,9 +473,7 @@ const char* AAResetDamage::getMenuText()
AAResetDamage * AAResetDamage::clone() const AAResetDamage * AAResetDamage::clone() const
{ {
AAResetDamage * a = NEW AAResetDamage(*this); return NEW AAResetDamage(*this);
a->isClone = 1;
return a;
} }
@@ -528,9 +514,7 @@ const char * AAFizzler::getMenuText()
AAFizzler* AAFizzler::clone() const AAFizzler* AAFizzler::clone() const
{ {
AAFizzler * a = NEW AAFizzler(*this); return NEW AAFizzler(*this);
a->isClone = 1;
return a;
} }
// BanishCard implementations // BanishCard implementations
// Bury // Bury
@@ -558,9 +542,7 @@ const char * AABuryCard::getMenuText()
AABuryCard * AABuryCard::clone() const AABuryCard * AABuryCard::clone() const
{ {
AABuryCard * a = NEW AABuryCard(*this); return NEW AABuryCard(*this);
a->isClone = 1;
return a;
} }
// Destroy // Destroy
@@ -588,9 +570,7 @@ const char * AADestroyCard::getMenuText()
AADestroyCard * AADestroyCard::clone() const AADestroyCard * AADestroyCard::clone() const
{ {
AADestroyCard * a = NEW AADestroyCard(*this); return NEW AADestroyCard(*this);
a->isClone = 1;
return a;
} }
// Sacrifice // Sacrifice
@@ -622,9 +602,7 @@ const char * AASacrificeCard::getMenuText()
AASacrificeCard * AASacrificeCard::clone() const AASacrificeCard * AASacrificeCard::clone() const
{ {
AASacrificeCard * a = NEW AASacrificeCard(*this); return NEW AASacrificeCard(*this);
a->isClone = 1;
return a;
} }
// Discard // Discard
@@ -657,9 +635,7 @@ const char * AADiscardCard::getMenuText()
AADiscardCard * AADiscardCard::clone() const AADiscardCard * AADiscardCard::clone() const
{ {
AADiscardCard * a = NEW AADiscardCard(*this); return NEW AADiscardCard(*this);
a->isClone = 1;
return a;
} }
AADrawer::AADrawer(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, string nbcardsStr, AADrawer::AADrawer(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, string nbcardsStr,
@@ -709,9 +685,7 @@ const char * AADrawer::getMenuText()
AADrawer * AADrawer::clone() const AADrawer * AADrawer::clone() const
{ {
AADrawer * a = NEW AADrawer(*this); return NEW AADrawer(*this);
a->isClone = 1;
return a;
} }
// AAFrozen: Prevent a card from untapping during next untap phase // AAFrozen: Prevent a card from untapping during next untap phase
@@ -740,9 +714,7 @@ const char * AAFrozen::getMenuText()
AAFrozen * AAFrozen::clone() const AAFrozen * AAFrozen::clone() const
{ {
AAFrozen * a = NEW AAFrozen(*this); return NEW AAFrozen(*this);
a->isClone = 1;
return a;
} }
// chose a new target for an aura or enchantment and equip it note: VERY basic right now. // chose a new target for an aura or enchantment and equip it note: VERY basic right now.
@@ -809,7 +781,6 @@ const char * AANewTarget::getMenuText()
AANewTarget * AANewTarget::clone() const AANewTarget * AANewTarget::clone() const
{ {
AANewTarget * a = NEW AANewTarget(*this); AANewTarget * a = NEW AANewTarget(*this);
a->isClone = 1;
a->oneShot = 1; a->oneShot = 1;
return a; return a;
} }
@@ -888,7 +859,6 @@ const char * AAMorph::getMenuText()
AAMorph * AAMorph::clone() const AAMorph * AAMorph::clone() const
{ {
AAMorph * a = NEW AAMorph(*this); AAMorph * a = NEW AAMorph(*this);
a->isClone = 1;
a->forceDestroy = 1; a->forceDestroy = 1;
return a; return a;
} }
@@ -1299,14 +1269,13 @@ const char * AADynamic::getMenuText()
AADynamic * AADynamic::clone() const AADynamic * AADynamic::clone() const
{ {
AADynamic * a = NEW AADynamic(*this); AADynamic * a = NEW AADynamic(*this);
a->isClone = 1; a->storedAbility = storedAbility? storedAbility->clone() : NULL;
return a; return a;
} }
AADynamic::~AADynamic() AADynamic::~AADynamic()
{ {
if (!isClone) SAFE_DELETE(storedAbility);
SAFE_DELETE(storedAbility);
} }
//AALifer //AALifer
@@ -1348,9 +1317,7 @@ const char * AALifer::getMenuText()
AALifer * AALifer::clone() const AALifer * AALifer::clone() const
{ {
AALifer * a = NEW AALifer(*this); return NEW AALifer(*this);
a->isClone = 1;
return a;
} }
@@ -1389,9 +1356,7 @@ const char * AASetHand::getMenuText()
AASetHand * AASetHand::clone() const AASetHand * AASetHand::clone() const
{ {
AASetHand * a = NEW AASetHand(*this); return NEW AASetHand(*this);
a->isClone = 1;
return a;
} }
//Lifeset //Lifeset
@@ -1432,7 +1397,6 @@ AALifeSet * AALifeSet::clone() const
{ {
AALifeSet * a = NEW AALifeSet(*this); AALifeSet * a = NEW AALifeSet(*this);
a->life = NEW WParsedInt(*(a->life)); a->life = NEW WParsedInt(*(a->life));
a->isClone = 1;
return a; return a;
} }
@@ -1518,9 +1482,7 @@ ostream& AACloner::toString(ostream& out) const
AACloner * AACloner::clone() const AACloner * AACloner::clone() const
{ {
AACloner * a = NEW AACloner(*this); return NEW AACloner(*this);
a->isClone = 1;
return a;
} }
AACloner::~AACloner() AACloner::~AACloner()
{ {
@@ -1599,7 +1561,6 @@ ACastRestriction * ACastRestriction::clone() const
ACastRestriction * a = NEW ACastRestriction(*this); ACastRestriction * a = NEW ACastRestriction(*this);
a->value = NEW WParsedInt(*(a->value)); a->value = NEW WParsedInt(*(a->value));
a->restrictionsScope = restrictionsScope->clone(); a->restrictionsScope = restrictionsScope->clone();
a->isClone = 1;
return a; return a;
} }
@@ -1632,7 +1593,6 @@ AInstantCastRestrictionUEOT * AInstantCastRestrictionUEOT::clone() const
{ {
AInstantCastRestrictionUEOT * a = NEW AInstantCastRestrictionUEOT(*this); AInstantCastRestrictionUEOT * a = NEW AInstantCastRestrictionUEOT(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -1756,9 +1716,7 @@ const char * AAMover::getMenuText(TargetChooser * tc)
AAMover * AAMover::clone() const AAMover * AAMover::clone() const
{ {
AAMover * a = NEW AAMover(*this); return NEW AAMover(*this);
a->isClone = 1;
return a;
} }
//Random Discard //Random Discard
@@ -1801,9 +1759,7 @@ const char * AARandomDiscarder::getMenuText()
AARandomDiscarder * AARandomDiscarder::clone() const AARandomDiscarder * AARandomDiscarder::clone() const
{ {
AARandomDiscarder * a = NEW AARandomDiscarder(*this); return NEW AARandomDiscarder(*this);
a->isClone = 1;
return a;
} }
// Shuffle // Shuffle
@@ -1839,9 +1795,7 @@ const char * AAShuffle::getMenuText()
AAShuffle * AAShuffle::clone() const AAShuffle * AAShuffle::clone() const
{ {
AAShuffle * a = NEW AAShuffle(*this); return NEW AAShuffle(*this);
a->isClone = 1;
return a;
} }
// Remove Mana From ManaPool // Remove Mana From ManaPool
@@ -1910,7 +1864,6 @@ AARemoveMana * AARemoveMana::clone() const
{ {
AARemoveMana * a = NEW AARemoveMana(*this); AARemoveMana * a = NEW AARemoveMana(*this);
a->mManaDesc = mManaDesc ? NEW ManaCost(mManaDesc) : NULL; a->mManaDesc = mManaDesc ? NEW ManaCost(mManaDesc) : NULL;
a->isClone = 1;
return a; return a;
} }
@@ -1946,9 +1899,7 @@ const char * AATapper::getMenuText()
AATapper * AATapper::clone() const AATapper * AATapper::clone() const
{ {
AATapper * a = NEW AATapper(*this); return NEW AATapper(*this);
a->isClone = 1;
return a;
} }
//AA Untapper //AA Untapper
@@ -1978,9 +1929,7 @@ const char * AAUntapper::getMenuText()
AAUntapper * AAUntapper::clone() const AAUntapper * AAUntapper::clone() const
{ {
AAUntapper * a = NEW AAUntapper(*this); return NEW AAUntapper(*this);
a->isClone = 1;
return a;
} }
AAWhatsMax::AAWhatsMax(int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost, int value) : AAWhatsMax::AAWhatsMax(int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost, int value) :
@@ -2001,9 +1950,7 @@ int AAWhatsMax::resolve()
AAWhatsMax * AAWhatsMax::clone() const AAWhatsMax * AAWhatsMax::clone() const
{ {
AAWhatsMax * a = NEW AAWhatsMax(*this); return NEW AAWhatsMax(*this);
a->isClone = 1;
return a;
} }
// Win Game // Win Game
@@ -2058,9 +2005,7 @@ const char * AAWinGame::getMenuText()
AAWinGame * AAWinGame::clone() const AAWinGame * AAWinGame::clone() const
{ {
AAWinGame * a = NEW AAWinGame(*this); return NEW AAWinGame(*this);
a->isClone = 1;
return a;
} }
//Generic Abilities //Generic Abilities
@@ -2101,9 +2046,7 @@ const char * IfThenAbility::getMenuText()
IfThenAbility * IfThenAbility::clone() const IfThenAbility * IfThenAbility::clone() const
{ {
IfThenAbility * a = NEW IfThenAbility(*this); return NEW IfThenAbility(*this);
a->isClone = 1;
return a;
} }
// //
@@ -2171,7 +2114,6 @@ MayAbility * MayAbility::clone() const
{ {
MayAbility * a = NEW MayAbility(*this); MayAbility * a = NEW MayAbility(*this);
a->ability = ability->clone(); a->ability = ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -2254,20 +2196,24 @@ const char * MultiAbility::getMenuText()
MultiAbility * MultiAbility::clone() const MultiAbility * MultiAbility::clone() const
{ {
MultiAbility * a = NEW MultiAbility(*this); MultiAbility * a = NEW MultiAbility(*this);
a->isClone = 1; a->abilities.clear();
vector<int>::size_type sz = abilities.size();
for (size_t i = 0; i < sz; i++)
{
a->abilities.push_back(abilities[i]->clone());
}
return a; return a;
} }
MultiAbility::~MultiAbility() MultiAbility::~MultiAbility()
{ {
if (!isClone)
vector<int>::size_type sz = abilities.size();
for (size_t i = 0; i < sz; i++)
{ {
vector<int>::size_type sz = abilities.size(); SAFE_DELETE(abilities[i]);
for (size_t i = 0; i < sz; i++)
{
SAFE_DELETE(abilities[i]);
}
} }
abilities.clear(); abilities.clear();
} }
@@ -2342,10 +2288,6 @@ GenericTargetAbility * GenericTargetAbility::clone() const
{ {
GenericTargetAbility * a = NEW GenericTargetAbility(*this); GenericTargetAbility * a = NEW GenericTargetAbility(*this);
a->ability = ability->clone(); a->ability = ability->clone();
a->cost = NEW ManaCost();
a->cost->copy(cost);
if (tc)
a->tc = tc->clone();
return a; return a;
} }
@@ -2466,9 +2408,7 @@ void AAlterCost::decreaseTheCost(MTGCardInstance * card)
AAlterCost * AAlterCost::clone() const AAlterCost * AAlterCost::clone() const
{ {
AAlterCost * a = NEW AAlterCost(*this); return NEW AAlterCost(*this);
a->isClone = 1;
return a;
} }
AAlterCost::~AAlterCost() AAlterCost::~AAlterCost()
@@ -2770,9 +2710,7 @@ const char * ATransformer::getMenuText()
ATransformer * ATransformer::clone() const ATransformer * ATransformer::clone() const
{ {
ATransformer * a = NEW ATransformer(*this); return NEW ATransformer(*this);
a->isClone = 1;
return a;
} }
ATransformer::~ATransformer() ATransformer::~ATransformer()
@@ -2803,7 +2741,6 @@ ATransformerInstant * ATransformerInstant::clone() const
{ {
ATransformerInstant * a = NEW ATransformerInstant(*this); ATransformerInstant * a = NEW ATransformerInstant(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -2835,7 +2772,6 @@ PTInstant * PTInstant::clone() const
{ {
PTInstant * a = NEW PTInstant(*this); PTInstant * a = NEW PTInstant(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -2868,7 +2804,6 @@ ASwapPTUEOT * ASwapPTUEOT::clone() const
{ {
ASwapPTUEOT * a = NEW ASwapPTUEOT(*this); ASwapPTUEOT * a = NEW ASwapPTUEOT(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -2980,9 +2915,7 @@ int ALoseAbilities::destroy()
ALoseAbilities * ALoseAbilities::clone() const ALoseAbilities * ALoseAbilities::clone() const
{ {
ALoseAbilities * a = NEW ALoseAbilities(*this); return NEW ALoseAbilities(*this);
a->isClone = 1;
return a;
} }
//ALoseSubtypes //ALoseSubtypes
@@ -3025,9 +2958,7 @@ int ALoseSubtypes::destroy()
ALoseSubtypes * ALoseSubtypes::clone() const ALoseSubtypes * ALoseSubtypes::clone() const
{ {
ALoseSubtypes * a = NEW ALoseSubtypes(*this); return NEW ALoseSubtypes(*this);
a->isClone = 1;
return a;
} }
//APreventDamageTypes //APreventDamageTypes
@@ -3077,7 +3008,7 @@ int APreventDamageTypes::destroy()
APreventDamageTypes * APreventDamageTypes::clone() const APreventDamageTypes * APreventDamageTypes::clone() const
{ {
APreventDamageTypes * a = NEW APreventDamageTypes(*this); APreventDamageTypes * a = NEW APreventDamageTypes(*this);
a->isClone = 1; a->re = NULL;
return a; return a;
} }
@@ -3120,7 +3051,6 @@ APreventDamageTypesUEOT * APreventDamageTypesUEOT::clone() const
{ {
APreventDamageTypesUEOT * a = NEW APreventDamageTypesUEOT(*this); APreventDamageTypesUEOT * a = NEW APreventDamageTypesUEOT(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->isClone = 1;
return a; return a;
} }
@@ -3194,9 +3124,7 @@ return "Fading";
AVanishing * AVanishing::clone() const AVanishing * AVanishing::clone() const
{ {
AVanishing * a = NEW AVanishing(*this); return NEW AVanishing(*this);
a->isClone = 1;
return a;
} }
AVanishing::~AVanishing() AVanishing::~AVanishing()
@@ -3283,14 +3211,13 @@ ostream& AUpkeep::toString(ostream& out) const
AUpkeep * AUpkeep::clone() const AUpkeep * AUpkeep::clone() const
{ {
AUpkeep * a = NEW AUpkeep(*this); AUpkeep * a = NEW AUpkeep(*this);
a->isClone = 1; a->ability = ability->clone();
return a; return a;
} }
AUpkeep::~AUpkeep() AUpkeep::~AUpkeep()
{ {
if (!isClone) SAFE_DELETE(ability);
SAFE_DELETE(ability);
} }
//A Phase based Action //A Phase based Action
@@ -3372,7 +3299,6 @@ APhaseAction * APhaseAction::clone() const
APhaseAction * a = NEW APhaseAction(*this); APhaseAction * a = NEW APhaseAction(*this);
if(forcedestroy == false) if(forcedestroy == false)
a->forceDestroy = -1;// we want this ability to stay alive until it resolves. a->forceDestroy = -1;// we want this ability to stay alive until it resolves.
a->isClone = 1;
return a; return a;
} }
@@ -3407,7 +3333,6 @@ APhaseActionGeneric * APhaseActionGeneric::clone() const
APhaseActionGeneric * a = NEW APhaseActionGeneric(*this); APhaseActionGeneric * a = NEW APhaseActionGeneric(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->oneShot = 1; a->oneShot = 1;
a->isClone = 1;
return a; return a;
} }
@@ -3617,14 +3542,13 @@ const char * ABlink::getMenuText()
ABlink * ABlink::clone() const ABlink * ABlink::clone() const
{ {
ABlink * a = NEW ABlink(*this); ABlink * a = NEW ABlink(*this);
a->isClone = 1; a->stored = stored ? stored->clone() : NULL;
a->forceDestroy = -1; a->forceDestroy = -1;
return a; return a;
}; };
ABlink::~ABlink() ABlink::~ABlink()
{ {
if (!isClone) SAFE_DELETE(stored);
SAFE_DELETE(stored);
} }
ABlinkGeneric::ABlinkGeneric(int _id, MTGCardInstance * card, MTGCardInstance * _target,bool blinkueot,bool blinkForSource,bool blinkhand,MTGAbility * stored) : ABlinkGeneric::ABlinkGeneric(int _id, MTGCardInstance * card, MTGCardInstance * _target,bool blinkueot,bool blinkForSource,bool blinkhand,MTGAbility * stored) :
@@ -3651,7 +3575,6 @@ ABlinkGeneric * ABlinkGeneric::clone() const
ABlinkGeneric * a = NEW ABlinkGeneric(*this); ABlinkGeneric * a = NEW ABlinkGeneric(*this);
a->ability = this->ability->clone(); a->ability = this->ability->clone();
a->oneShot = 1; a->oneShot = 1;
a->isClone = 1;
return a; return a;
} }
+80 -39
View File
@@ -858,7 +858,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
AManaProducer * amp = dynamic_cast<AManaProducer*> (a); AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
if (amp) if (amp)
{ {
amp->cost = cost; amp->setCost(cost);
if (cost && card->typeAsTarget() == TARGET_CARD) if (cost && card->typeAsTarget() == TARGET_CARD)
cost->setExtraCostsAction(a, card); cost->setExtraCostsAction(a, card);
amp->oneShot = 0; amp->oneShot = 0;
@@ -873,7 +873,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
AEquip *ae = dynamic_cast<AEquip*> (a); AEquip *ae = dynamic_cast<AEquip*> (a);
if (ae) if (ae)
{ {
ae->cost = cost; ae->setCost(cost);
if (!tc) if (!tc)
{ {
TargetChooserFactory tcf; TargetChooserFactory tcf;
@@ -3302,6 +3302,42 @@ MTGAbility * AbilityFactory::getManaReduxAbility(string s, int id, Spell *spell,
return NEW AAlterCost(id, card, target, amount, color); return NEW AAlterCost(id, card, target, amount, color);
} }
MTGAbility::MTGAbility(const MTGAbility& a): ActionElement(a)
{
//Todo get rid of menuText, it is only used as a placeholder in getMenuText, for something that could be a string
for (int i = 0; i < 50; ++i)
{
menuText[i] = a.menuText[i];
}
game = a.game;
oneShot = a.oneShot;
forceDestroy = a.forceDestroy;
forcedAlive = a.forcedAlive;
canBeInterrupted = a.canBeInterrupted;
//costs get copied, and will be deleted in the destructor
mCost = a.mCost ? NEW ManaCost(a.mCost) : NULL;
//alternative costs are not deleted in the destructor...who deletes them???
alternative = a.alternative; // ? NEW ManaCost(a.alternative) : NULL;
BuyBack = a.BuyBack; //? NEW ManaCost(a.BuyBack) : NULL;
FlashBack = a.FlashBack; // ? NEW ManaCost(a.FlashBack) : NULL;
Retrace = a.Retrace;// ? NEW ManaCost(a.Retrace) : NULL;
morph = a.morph; //? NEW ManaCost(a.morph) : NULL;
suspend = a.suspend;// ? NEW ManaCost(a.suspend) : NULL;
//Those two are pointers, but we don't delete them in the destructor, no need to copy them
target = a.target;
source = a.source;
aType = a.aType;
naType = a.naType;
abilitygranted = a.abilitygranted;
};
MTGAbility::MTGAbility(int id, MTGCardInstance * card) : MTGAbility::MTGAbility(int id, MTGCardInstance * card) :
ActionElement(id) ActionElement(id)
{ {
@@ -3309,7 +3345,7 @@ MTGAbility::MTGAbility(int id, MTGCardInstance * card) :
source = card; source = card;
target = card; target = card;
aType = MTGAbility::UNKNOWN; aType = MTGAbility::UNKNOWN;
cost = NULL; mCost = NULL;
forceDestroy = 0; forceDestroy = 0;
oneShot = 0; oneShot = 0;
canBeInterrupted = true; canBeInterrupted = true;
@@ -3322,12 +3358,22 @@ MTGAbility::MTGAbility(int id, MTGCardInstance * _source, Targetable * _target)
source = _source; source = _source;
target = _target; target = _target;
aType = MTGAbility::UNKNOWN; aType = MTGAbility::UNKNOWN;
cost = NULL; mCost = NULL;
forceDestroy = 0; forceDestroy = 0;
oneShot = 0; oneShot = 0;
canBeInterrupted = true; canBeInterrupted = true;
} }
void MTGAbility::setCost(ManaCost * cost, bool forceDelete)
{
if (mCost) {
DebugTrace("WARNING: Mtgability.cpp, attempt to set cost when previous cost is not null");
if (forceDelete)
delete(mCost);
}
mCost = cost;
}
int MTGAbility::stillInUse(MTGCardInstance * card) int MTGAbility::stillInUse(MTGCardInstance * card)
{ {
if (card == source || card == target) if (card == source || card == target)
@@ -3337,10 +3383,7 @@ int MTGAbility::stillInUse(MTGCardInstance * card)
MTGAbility::~MTGAbility() MTGAbility::~MTGAbility()
{ {
if (!isClone) SAFE_DELETE(mCost);
{
SAFE_DELETE(cost);
}
} }
int MTGAbility::addToGame() int MTGAbility::addToGame()
@@ -3392,7 +3435,7 @@ int MTGAbility::fireAbility()
ostream& MTGAbility::toString(ostream& out) const ostream& MTGAbility::toString(ostream& out) const
{ {
return out << "MTGAbility ::: menuText : " << menuText << " ; game : " << game << " ; forceDestroy : " << forceDestroy return out << "MTGAbility ::: menuText : " << menuText << " ; game : " << game << " ; forceDestroy : " << forceDestroy
<< " ; cost : " << cost << " ; target : " << target << " ; aType : " << aType << " ; source : " << source; << " ; mCost : " << mCost << " ; target : " << target << " ; aType : " << aType << " ; source : " << source;
} }
NestedAbility::NestedAbility(MTGAbility * _ability) NestedAbility::NestedAbility(MTGAbility * _ability)
@@ -3406,7 +3449,7 @@ ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _c
MTGAbility(id, card), restrictions(restrictions), needsTapping(0),limit(limit),sideEffect(sideEffect),usesBeforeSideEffects(usesBeforeSideEffects) MTGAbility(id, card), restrictions(restrictions), needsTapping(0),limit(limit),sideEffect(sideEffect),usesBeforeSideEffects(usesBeforeSideEffects)
{ {
counters = 0; counters = 0;
cost = _cost; setCost(_cost);
abilityCost = 0; abilityCost = 0;
sa = NULL; sa = NULL;
} }
@@ -3473,6 +3516,7 @@ int ActivatedAbility::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
if (card == source && source->controller() == player && (!needsTapping || (!source->isTapped() if (card == source && source->controller() == player && (!needsTapping || (!source->isTapped()
&& !source->hasSummoningSickness()))) && !source->hasSummoningSickness())))
{ {
ManaCost * cost = getCost();
if (!cost) if (!cost)
return 1; return 1;
cost->setExtraCostsAction(this, card); cost->setExtraCostsAction(this, card);
@@ -3492,6 +3536,7 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card)
if (!isReactingToClick(card)) if (!isReactingToClick(card))
return 0; return 0;
Player * player = game->currentlyActing(); Player * player = game->currentlyActing();
ManaCost * cost = getCost();
if (cost) if (cost)
{ {
if (!cost->isExtraPaymentSet()) if (!cost->isExtraPaymentSet())
@@ -3514,6 +3559,7 @@ int ActivatedAbility::reactToTargetClick(Targetable * object)
if (!isReactingToTargetClick(object)) if (!isReactingToTargetClick(object))
return 0; return 0;
Player * player = game->currentlyActing(); Player * player = game->currentlyActing();
ManaCost * cost = getCost();
if (cost) if (cost)
{ {
if (object->typeAsTarget() == TARGET_CARD) if (object->typeAsTarget() == TARGET_CARD)
@@ -3542,6 +3588,7 @@ int ActivatedAbility::activateAbility()
fmp = af.getCoreAbility(this); fmp = af.getCoreAbility(this);
AManaProducer * amp = dynamic_cast<AManaProducer *> (this); AManaProducer * amp = dynamic_cast<AManaProducer *> (this);
AManaProducer * femp = dynamic_cast<AManaProducer *> (fmp); AManaProducer * femp = dynamic_cast<AManaProducer *> (fmp);
ManaCost * cost = getCost();
if((amp||femp) && cost && cost->extraCosts) if((amp||femp) && cost && cost->extraCosts)
{ {
for(unsigned int i = 0; i < cost->extraCosts->costs.size();i++) for(unsigned int i = 0; i < cost->extraCosts->costs.size();i++)
@@ -3612,14 +3659,9 @@ void ActivatedAbility::activateSideEffect()
ActivatedAbility::~ActivatedAbility() ActivatedAbility::~ActivatedAbility()
{ {
//Ok, this will probably lead to crashes, maybe with lord abilities involving "X" costs.
// If that's the case, we need to improve the clone() method of GenericActivatedAbility and GenericTargetAbility, I think
// Erwan 2004/04/25
//if (!isClone){
SAFE_DELETE(abilityCost); SAFE_DELETE(abilityCost);
SAFE_DELETE(sideEffect); SAFE_DELETE(sideEffect);
SAFE_DELETE(sa); SAFE_DELETE(sa);
//}
} }
ostream& ActivatedAbility::toString(ostream& out) const ostream& ActivatedAbility::toString(ostream& out) const
@@ -3663,6 +3705,7 @@ int TargetAbility::reactToClick(MTGCardInstance * card)
{ {
if (isReactingToClick(card)) if (isReactingToClick(card))
{ {
ManaCost * cost = getCost();
if (cost && !cost->isExtraPaymentSet()) if (cost && !cost->isExtraPaymentSet())
{ {
game->mExtraPayment = cost->extraCosts; game->mExtraPayment = cost->extraCosts;
@@ -3716,9 +3759,14 @@ int TargetAbility::resolve()
Targetable * t = tc->getNextTarget(); Targetable * t = tc->getNextTarget();
if (t && ability) if (t && ability)
{ {
ManaCost * diff = abilityCost->Diff(cost); source->X = 0;
source->X = diff->hasX(); if (abilityCost)
delete (diff); {
ManaCost * diff = abilityCost->Diff(getCost());
source->X = diff->hasX();
delete (diff);
}
ability->target = t; ability->target = t;
//do nothing if the target controller responded by phasing out the target. //do nothing if the target controller responded by phasing out the target.
if (t->typeAsTarget() == TARGET_CARD && ((MTGCardInstance*)t)->isPhased) if (t->typeAsTarget() == TARGET_CARD && ((MTGCardInstance*)t)->isPhased)
@@ -3740,8 +3788,7 @@ const char * TargetAbility::getMenuText()
TargetAbility::~TargetAbility() TargetAbility::~TargetAbility()
{ {
if (!isClone) SAFE_DELETE(ability);
SAFE_DELETE(ability);
} }
ostream& TargetAbility::toString(ostream& out) const ostream& TargetAbility::toString(ostream& out) const
@@ -4009,9 +4056,7 @@ TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * ta
TriggerAtPhase* TriggerAtPhase::clone() const TriggerAtPhase* TriggerAtPhase::clone() const
{ {
TriggerAtPhase * a = NEW TriggerAtPhase(*this); return NEW TriggerAtPhase(*this);
a->isClone = 1;
return a;
} }
TriggerNextPhase::TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target, int _phaseId, int who,bool sourceUntapped, bool sourceTap,bool once) : TriggerNextPhase::TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target, int _phaseId, int who,bool sourceUntapped, bool sourceTap,bool once) :
@@ -4036,9 +4081,7 @@ int TriggerNextPhase::testDestroy()
TriggerNextPhase* TriggerNextPhase::clone() const TriggerNextPhase* TriggerNextPhase::clone() const
{ {
TriggerNextPhase * a = NEW TriggerNextPhase(*this); return NEW TriggerNextPhase(*this);
a->isClone = 1;
return a;
} }
GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a, GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,
@@ -4156,12 +4199,9 @@ int GenericTriggeredAbility::testDestroy()
GenericTriggeredAbility::~GenericTriggeredAbility() GenericTriggeredAbility::~GenericTriggeredAbility()
{ {
if (!isClone) delete t;
{ delete ability;
delete t; SAFE_DELETE(destroyCondition);
delete ability;
SAFE_DELETE(destroyCondition);
}
} }
const char * GenericTriggeredAbility::getMenuText() const char * GenericTriggeredAbility::getMenuText()
@@ -4171,8 +4211,10 @@ const char * GenericTriggeredAbility::getMenuText()
GenericTriggeredAbility* GenericTriggeredAbility::clone() const GenericTriggeredAbility* GenericTriggeredAbility::clone() const
{ {
GenericTriggeredAbility * a = NEW GenericTriggeredAbility(*this); GenericTriggeredAbility * a = NEW GenericTriggeredAbility(*this);
a->isClone = 1; a->t = t->clone();
a->ability = ability->clone();
a->destroyCondition = destroyCondition->clone();
return a; return a;
} }
@@ -4188,7 +4230,7 @@ AManaProducer::AManaProducer(int id, MTGCardInstance * card, Targetable * t, Man
{ {
aType = MTGAbility::MANA_PRODUCER; aType = MTGAbility::MANA_PRODUCER;
cost = _cost; setCost(_cost);
output = _output; output = _output;
menutext = ""; menutext = "";
@@ -4202,6 +4244,7 @@ int AManaProducer::isReactingToClick(MTGCardInstance * _card, ManaCost * mana)
if (_card == source && (!tap || !source->isTapped()) && game->currentlyActing()->game->inPlay->hasCard(source) if (_card == source && (!tap || !source->isTapped()) && game->currentlyActing()->game->inPlay->hasCard(source)
&& (source->hasType(Subtypes::TYPE_LAND) || !tap || !source->hasSummoningSickness()) && !source->isPhased) && (source->hasType(Subtypes::TYPE_LAND) || !tap || !source->hasSummoningSickness()) && !source->isPhased)
{ {
ManaCost * cost = getCost();
if (!cost || mana->canAfford(cost)) if (!cost || mana->canAfford(cost))
{ {
result = 1; result = 1;
@@ -4236,6 +4279,8 @@ int AManaProducer::reactToClick(MTGCardInstance * _card)
return 0; return 0;
if(!ActivatedAbility::isReactingToClick(_card)) if(!ActivatedAbility::isReactingToClick(_card))
return 0; return 0;
ManaCost * cost = getCost();
if (cost) if (cost)
{ {
cost->setExtraCostsAction(this, _card); cost->setExtraCostsAction(this, _card);
@@ -4302,18 +4347,14 @@ const char * AManaProducer::getMenuText()
AManaProducer::~AManaProducer() AManaProducer::~AManaProducer()
{ {
SAFE_DELETE(cost);
SAFE_DELETE(output); SAFE_DELETE(output);
} }
AManaProducer * AManaProducer::clone() const AManaProducer * AManaProducer::clone() const
{ {
AManaProducer * a = NEW AManaProducer(*this); AManaProducer * a = NEW AManaProducer(*this);
a->cost = NEW ManaCost();
a->output = NEW ManaCost(); a->output = NEW ManaCost();
a->cost->copy(cost);
a->output->copy(output); a->output->copy(output);
a->isClone = 1;
return a; return a;
} }
+1 -3
View File
@@ -53,9 +53,7 @@ bool MTGGamePhase::CheckUserInput(JButton key)
MTGGamePhase * MTGGamePhase::clone() const MTGGamePhase * MTGGamePhase::clone() const
{ {
MTGGamePhase * a = NEW MTGGamePhase(*this); return NEW MTGGamePhase(*this);
a->isClone = 1;
return a;
} }
ostream& MTGGamePhase::toString(ostream& out) const ostream& MTGGamePhase::toString(ostream& out) const
+26 -76
View File
@@ -278,9 +278,7 @@ void MTGEventBonus::Render()
MTGEventBonus * MTGEventBonus::clone() const MTGEventBonus * MTGEventBonus::clone() const
{ {
MTGEventBonus * a = NEW MTGEventBonus(*this); return NEW MTGEventBonus(*this);
a->isClone = 1;
return a;
} }
// //
@@ -469,9 +467,7 @@ ostream& MTGPutInPlayRule::toString(ostream& out) const
MTGPutInPlayRule * MTGPutInPlayRule::clone() const MTGPutInPlayRule * MTGPutInPlayRule::clone() const
{ {
MTGPutInPlayRule * a = NEW MTGPutInPlayRule(*this); return NEW MTGPutInPlayRule(*this);
a->isClone = 1;
return a;
} }
@@ -593,9 +589,7 @@ ostream& MTGKickerRule::toString(ostream& out) const
MTGKickerRule * MTGKickerRule::clone() const MTGKickerRule * MTGKickerRule::clone() const
{ {
MTGKickerRule * a = NEW MTGKickerRule(*this); return NEW MTGKickerRule(*this);
a->isClone = 1;
return a;
} }
@@ -757,9 +751,7 @@ ostream& MTGAlternativeCostRule::toString(ostream& out) const
MTGAlternativeCostRule * MTGAlternativeCostRule::clone() const MTGAlternativeCostRule * MTGAlternativeCostRule::clone() const
{ {
MTGAlternativeCostRule * a = NEW MTGAlternativeCostRule(*this); return NEW MTGAlternativeCostRule(*this);
a->isClone = 1;
return a;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -811,9 +803,7 @@ ostream& MTGBuyBackRule::toString(ostream& out) const
MTGBuyBackRule * MTGBuyBackRule::clone() const MTGBuyBackRule * MTGBuyBackRule::clone() const
{ {
MTGBuyBackRule * a = NEW MTGBuyBackRule(*this); return NEW MTGBuyBackRule(*this);
a->isClone = 1;
return a;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -860,9 +850,7 @@ ostream& MTGFlashBackRule::toString(ostream& out) const
} }
MTGFlashBackRule * MTGFlashBackRule::clone() const MTGFlashBackRule * MTGFlashBackRule::clone() const
{ {
MTGFlashBackRule * a = NEW MTGFlashBackRule(*this); return NEW MTGFlashBackRule(*this);
a->isClone = 1;
return a;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -915,9 +903,7 @@ ostream& MTGRetraceRule::toString(ostream& out) const
} }
MTGRetraceRule * MTGRetraceRule::clone() const MTGRetraceRule * MTGRetraceRule::clone() const
{ {
MTGRetraceRule * a = NEW MTGRetraceRule(*this); return NEW MTGRetraceRule(*this);
a->isClone = 1;
return a;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -985,7 +971,7 @@ int MTGSuspendRule::reactToClick(MTGCardInstance * card)
else else
{ {
alternateCost->setExtraCostsAction(this, card); alternateCost->setExtraCostsAction(this, card);
game->mExtraPayment = cost->suspend->extraCosts; game->mExtraPayment = getCost()->suspend->extraCosts;
return 0; return 0;
} }
card->paymenttype = MTGAbility::SUSPEND_COST; card->paymenttype = MTGAbility::SUSPEND_COST;
@@ -1016,9 +1002,7 @@ ostream& MTGSuspendRule::toString(ostream& out) const
} }
MTGSuspendRule * MTGSuspendRule::clone() const MTGSuspendRule * MTGSuspendRule::clone() const
{ {
MTGSuspendRule * a = NEW MTGSuspendRule(*this); return NEW MTGSuspendRule(*this);
a->isClone = 1;
return a;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -1146,9 +1130,7 @@ ostream& MTGMorphCostRule::toString(ostream& out) const
MTGMorphCostRule * MTGMorphCostRule::clone() const MTGMorphCostRule * MTGMorphCostRule::clone() const
{ {
MTGMorphCostRule * a = NEW MTGMorphCostRule(*this); return NEW MTGMorphCostRule(*this);
a->isClone = 1;
return a;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -1252,9 +1234,7 @@ ostream& MTGAttackRule::toString(ostream& out) const
MTGAttackRule * MTGAttackRule::clone() const MTGAttackRule * MTGAttackRule::clone() const
{ {
MTGAttackRule * a = NEW MTGAttackRule(*this); return NEW MTGAttackRule(*this);
a->isClone = 1;
return a;
} }
//this rules handles returning cards to combat triggers for activations. //this rules handles returning cards to combat triggers for activations.
@@ -1372,9 +1352,7 @@ ostream& MTGCombatTriggersRule::toString(ostream& out) const
MTGCombatTriggersRule * MTGCombatTriggersRule::clone() const MTGCombatTriggersRule * MTGCombatTriggersRule::clone() const
{ {
MTGCombatTriggersRule * a = NEW MTGCombatTriggersRule(*this); return NEW MTGCombatTriggersRule(*this);
a->isClone = 1;
return a;
} }
///------------ ///------------
@@ -1410,9 +1388,7 @@ int OtherAbilitiesEventReceiver::testDestroy()
OtherAbilitiesEventReceiver * OtherAbilitiesEventReceiver::clone() const OtherAbilitiesEventReceiver * OtherAbilitiesEventReceiver::clone() const
{ {
OtherAbilitiesEventReceiver * a = NEW OtherAbilitiesEventReceiver(*this); return NEW OtherAbilitiesEventReceiver(*this);
a->isClone = 1;
return a;
} }
MTGBlockRule::MTGBlockRule(int _id) : MTGBlockRule::MTGBlockRule(int _id) :
@@ -1467,9 +1443,7 @@ ostream& MTGBlockRule::toString(ostream& out) const
MTGBlockRule * MTGBlockRule::clone() const MTGBlockRule * MTGBlockRule::clone() const
{ {
MTGBlockRule * a = NEW MTGBlockRule(*this); return NEW MTGBlockRule(*this);
a->isClone = 1;
return a;
} }
// //
// Attacker chooses blockers order // Attacker chooses blockers order
@@ -1625,9 +1599,7 @@ ostream& MTGMomirRule::toString(ostream& out) const
MTGMomirRule * MTGMomirRule::clone() const MTGMomirRule * MTGMomirRule::clone() const
{ {
MTGMomirRule * a = NEW MTGMomirRule(*this); return NEW MTGMomirRule(*this);
a->isClone = 1;
return a;
} }
//stone hewer game mode //stone hewer game mode
@@ -1735,9 +1707,7 @@ ostream& MTGStoneHewerRule::toString(ostream& out) const
MTGStoneHewerRule * MTGStoneHewerRule::clone() const MTGStoneHewerRule * MTGStoneHewerRule::clone() const
{ {
MTGStoneHewerRule * a = NEW MTGStoneHewerRule(*this); return NEW MTGStoneHewerRule(*this);
a->isClone = 1;
return a;
} }
//------------------ //------------------
@@ -1782,9 +1752,7 @@ int MTGHermitRule::testDestroy()
MTGHermitRule * MTGHermitRule::clone() const MTGHermitRule * MTGHermitRule::clone() const
{ {
MTGHermitRule * a = NEW MTGHermitRule(*this); return NEW MTGHermitRule(*this);
a->isClone = 1;
return a;
} }
//-------------------- //--------------------
@@ -1903,9 +1871,7 @@ HUDDisplay::~HUDDisplay()
HUDDisplay * HUDDisplay::clone() const HUDDisplay * HUDDisplay::clone() const
{ {
HUDDisplay * a = NEW HUDDisplay(*this); return NEW HUDDisplay(*this);
a->isClone = 1;
return a;
} }
/* Persist */ /* Persist */
@@ -1966,9 +1932,7 @@ int MTGPersistRule::testDestroy()
} }
MTGPersistRule * MTGPersistRule::clone() const MTGPersistRule * MTGPersistRule::clone() const
{ {
MTGPersistRule * a = NEW MTGPersistRule(*this); return NEW MTGPersistRule(*this);
a->isClone = 1;
return a;
} }
//vampires rule //vampires rule
@@ -2044,9 +2008,7 @@ int MTGVampireRule::testDestroy()
} }
MTGVampireRule * MTGVampireRule::clone() const MTGVampireRule * MTGVampireRule::clone() const
{ {
MTGVampireRule * a = NEW MTGVampireRule(*this); return NEW MTGVampireRule(*this);
a->isClone = 1;
return a;
} }
///////////////////////////////////////////////// /////////////////////////////////////////////////
//unearth rule---------------------------------- //unearth rule----------------------------------
@@ -2108,9 +2070,7 @@ int MTGUnearthRule::testDestroy()
} }
MTGUnearthRule * MTGUnearthRule::clone() const MTGUnearthRule * MTGUnearthRule::clone() const
{ {
MTGUnearthRule * a = NEW MTGUnearthRule(*this); return NEW MTGUnearthRule(*this);
a->isClone = 1;
return a;
} }
//token clean up //token clean up
MTGTokensCleanup::MTGTokensCleanup(int _id) : MTGTokensCleanup::MTGTokensCleanup(int _id) :
@@ -2142,9 +2102,7 @@ int MTGTokensCleanup::testDestroy()
MTGTokensCleanup * MTGTokensCleanup::clone() const MTGTokensCleanup * MTGTokensCleanup::clone() const
{ {
MTGTokensCleanup * a = NEW MTGTokensCleanup(*this); return NEW MTGTokensCleanup(*this);
a->isClone = 1;
return a;
} }
/* Legend Rule */ /* Legend Rule */
@@ -2201,9 +2159,7 @@ ostream& MTGLegendRule::toString(ostream& out) const
} }
MTGLegendRule * MTGLegendRule::clone() const MTGLegendRule * MTGLegendRule::clone() const
{ {
MTGLegendRule * a = NEW MTGLegendRule(*this); return NEW MTGLegendRule(*this);
a->isClone = 1;
return a;
} }
/* PlaneWalker Rule */ /* PlaneWalker Rule */
@@ -2260,9 +2216,7 @@ ostream& MTGPlaneWalkerRule::toString(ostream& out) const
} }
MTGPlaneWalkerRule * MTGPlaneWalkerRule::clone() const MTGPlaneWalkerRule * MTGPlaneWalkerRule::clone() const
{ {
MTGPlaneWalkerRule * a = NEW MTGPlaneWalkerRule(*this); return NEW MTGPlaneWalkerRule(*this);
a->isClone = 1;
return a;
} }
/* Lifelink */ /* Lifelink */
@@ -2300,9 +2254,7 @@ ostream& MTGLifelinkRule::toString(ostream& out) const
} }
MTGLifelinkRule * MTGLifelinkRule::clone() const MTGLifelinkRule * MTGLifelinkRule::clone() const
{ {
MTGLifelinkRule * a = NEW MTGLifelinkRule(*this); return NEW MTGLifelinkRule(*this);
a->isClone = 1;
return a;
} }
/* Deathtouch */ /* Deathtouch */
@@ -2346,7 +2298,5 @@ int MTGDeathtouchRule::testDestroy()
MTGDeathtouchRule * MTGDeathtouchRule::clone() const MTGDeathtouchRule * MTGDeathtouchRule::clone() const
{ {
MTGDeathtouchRule * a = NEW MTGDeathtouchRule(*this); return NEW MTGDeathtouchRule(*this);
a->isClone = 1;
return a;
} }
+5 -4
View File
@@ -274,8 +274,7 @@ ManaCost::ManaCost(ManaCost * manaCost)
morph = NEW ManaCost( manaCost->morph ); morph = NEW ManaCost( manaCost->morph );
suspend = NEW ManaCost( manaCost->suspend ); suspend = NEW ManaCost( manaCost->suspend );
// TODO: Need to figure out if a deep copy is necessary extraCosts = manaCost->extraCosts ? manaCost->extraCosts->clone() : NULL;
extraCosts = manaCost->extraCosts;
} }
// Copy Constructor // Copy Constructor
@@ -301,8 +300,7 @@ ManaCost::ManaCost(const ManaCost& manaCost)
morph = NEW ManaCost( manaCost.morph ); morph = NEW ManaCost( manaCost.morph );
suspend = NEW ManaCost( manaCost.suspend ); suspend = NEW ManaCost( manaCost.suspend );
// TODO: Need to figure out if a deep copy is necessary extraCosts = manaCost.extraCosts ? manaCost.extraCosts->clone() : NULL;
extraCosts = manaCost.extraCosts;
} }
// operator= // operator=
@@ -674,6 +672,9 @@ int ManaCost::tryToPayHybrids(std::vector<ManaCostHybrid>& _hybrids, int _nbhybr
//compute the difference between two mana costs //compute the difference between two mana costs
ManaCost * ManaCost::Diff(ManaCost * _cost) ManaCost * ManaCost::Diff(ManaCost * _cost)
{ {
if (!_cost)
return NEW ManaCost(*this); //diff with null is equivalent to diff with 0
int8_t diff[(Constants::MTG_NB_COLORS + 1) * 2]; int8_t diff[(Constants::MTG_NB_COLORS + 1) * 2];
diff[Constants::MTG_NB_COLORS * 2] = Constants::MTG_NB_COLORS; diff[Constants::MTG_NB_COLORS * 2] = Constants::MTG_NB_COLORS;
for (int i = 0; i < Constants::MTG_NB_COLORS; i++) for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
+82
View File
@@ -369,6 +369,13 @@ ThisCounter::~ThisCounter()
SAFE_DELETE(counter); SAFE_DELETE(counter);
} }
ThisCounter* ThisCounter::clone() const
{
ThisCounter * a = NEW ThisCounter(*this);
a->counter = NEW Counter(NULL, counter->name.c_str(), counter->power, counter->toughness);
return a;
}
ThisOpponentlife::ThisOpponentlife(int olife) ThisOpponentlife::ThisOpponentlife(int olife)
{ {
comparisonCriterion = olife; comparisonCriterion = olife;
@@ -379,6 +386,11 @@ int ThisOpponentlife::match(MTGCardInstance * card)
return matchValue(card->controller()->opponent()->life); return matchValue(card->controller()->opponent()->life);
} }
ThisOpponentlife* ThisOpponentlife::clone() const
{
return NEW ThisOpponentlife(*this);
}
ThisControllerlife::ThisControllerlife(int life) ThisControllerlife::ThisControllerlife(int life)
{ {
comparisonCriterion = life; comparisonCriterion = life;
@@ -389,6 +401,11 @@ int ThisControllerlife::match(MTGCardInstance * card)
return matchValue(card->controller()->life); return matchValue(card->controller()->life);
} }
ThisControllerlife* ThisControllerlife::clone() const
{
return NEW ThisControllerlife(*this);
}
ThisPower::ThisPower(int power) ThisPower::ThisPower(int power)
{ {
comparisonCriterion = power; comparisonCriterion = power;
@@ -399,6 +416,11 @@ int ThisPower::match(MTGCardInstance * card)
return matchValue(card->power); return matchValue(card->power);
} }
ThisPower* ThisPower::clone() const
{
return NEW ThisPower(*this);
}
ThisEquip::ThisEquip(int equipment) ThisEquip::ThisEquip(int equipment)
{ {
comparisonCriterion = equipment; comparisonCriterion = equipment;
@@ -408,6 +430,11 @@ int ThisEquip::match(MTGCardInstance * card)
return matchValue(card->equipment); return matchValue(card->equipment);
} }
ThisEquip* ThisEquip::clone() const
{
return NEW ThisEquip(*this);
}
ThisAuras::ThisAuras(int auras) ThisAuras::ThisAuras(int auras)
{ {
comparisonCriterion = auras; comparisonCriterion = auras;
@@ -417,6 +444,11 @@ int ThisAuras::match(MTGCardInstance * card)
return matchValue(card->auras); return matchValue(card->auras);
} }
ThisAuras* ThisAuras::clone() const
{
return NEW ThisAuras(*this);
}
ThisOpponentDamageAmount::ThisOpponentDamageAmount(int damagecount) ThisOpponentDamageAmount::ThisOpponentDamageAmount(int damagecount)
{ {
comparisonCriterion = damagecount; comparisonCriterion = damagecount;
@@ -426,6 +458,11 @@ int ThisOpponentDamageAmount::match(MTGCardInstance * card)
return matchValue(card->controller()->opponent()->damageCount); return matchValue(card->controller()->opponent()->damageCount);
} }
ThisOpponentDamageAmount* ThisOpponentDamageAmount::clone() const
{
return NEW ThisOpponentDamageAmount(*this);
}
ThisUntapped::ThisUntapped(int untapped) ThisUntapped::ThisUntapped(int untapped)
{ {
comparisonCriterion = untapped; comparisonCriterion = untapped;
@@ -435,6 +472,11 @@ int ThisUntapped::match(MTGCardInstance * card)
return matchValue(!card->isTapped()); return matchValue(!card->isTapped());
} }
ThisUntapped* ThisUntapped::clone() const
{
return NEW ThisUntapped(*this);
}
ThisTapped::ThisTapped(int tapped) ThisTapped::ThisTapped(int tapped)
{ {
comparisonCriterion = tapped; comparisonCriterion = tapped;
@@ -444,6 +486,11 @@ int ThisTapped::match(MTGCardInstance * card)
return matchValue(card->isTapped()); return matchValue(card->isTapped());
} }
ThisTapped* ThisTapped::clone() const
{
return NEW ThisTapped(*this);
}
ThisAttacked::ThisAttacked(int attack) ThisAttacked::ThisAttacked(int attack)
{ {
@@ -456,6 +503,11 @@ int ThisAttacked::match(MTGCardInstance * card)
return matchValue(card->didattacked); return matchValue(card->didattacked);
} }
ThisAttacked* ThisAttacked::clone() const
{
return NEW ThisAttacked(*this);
}
ThisBlocked::ThisBlocked(int block) ThisBlocked::ThisBlocked(int block)
{ {
@@ -468,6 +520,11 @@ int ThisBlocked::match(MTGCardInstance * card)
return matchValue(card->didblocked); return matchValue(card->didblocked);
} }
ThisBlocked* ThisBlocked::clone() const
{
return NEW ThisBlocked(*this);
}
ThisNotBlocked::ThisNotBlocked(int unblocked) ThisNotBlocked::ThisNotBlocked(int unblocked)
{ {
@@ -480,6 +537,11 @@ int ThisNotBlocked::match(MTGCardInstance * card)
return matchValue(card->notblocked); return matchValue(card->notblocked);
} }
ThisNotBlocked* ThisNotBlocked::clone() const
{
return NEW ThisNotBlocked(*this);
}
ThisDamaged::ThisDamaged(int wasDealtDamage) ThisDamaged::ThisDamaged(int wasDealtDamage)
{ {
@@ -494,6 +556,11 @@ result = 1;
return matchValue(result); return matchValue(result);
} }
ThisDamaged* ThisDamaged::clone() const
{
return NEW ThisDamaged(*this);
}
ThisToughness::ThisToughness(int toughness) ThisToughness::ThisToughness(int toughness)
{ {
comparisonCriterion = toughness; comparisonCriterion = toughness;
@@ -504,6 +571,11 @@ int ThisToughness::match(MTGCardInstance * card)
return matchValue(card->toughness); return matchValue(card->toughness);
} }
ThisToughness* ThisToughness::clone() const
{
return NEW ThisToughness(*this);
}
ThisCounterAny::ThisCounterAny(int nb) ThisCounterAny::ThisCounterAny(int nb)
{ {
comparisonCriterion = nb; comparisonCriterion = nb;
@@ -519,6 +591,11 @@ int ThisCounterAny::match(MTGCardInstance * card)
return matchValue(result); return matchValue(result);
} }
ThisCounterAny * ThisCounterAny::clone() const
{
return NEW ThisCounterAny(*this);
}
ThisX::ThisX(int x) ThisX::ThisX(int x)
{ {
comparisonCriterion = x; comparisonCriterion = x;
@@ -528,3 +605,8 @@ int ThisX::match(MTGCardInstance * card)
{ {
return matchValue(card->X); return matchValue(card->X);
} }
ThisX * ThisX::clone() const
{
return NEW ThisX(*this);
}