Erwan
- Trying to add generic classes for Triggered abilities. PLEASE DO NOT USE THESE RIGHT NOW, Not Tested AT ALL !
This commit is contained in:
@@ -29,7 +29,6 @@ class ActionElement: public JGuiObject{
|
|||||||
int newPhase;
|
int newPhase;
|
||||||
int modal;
|
int modal;
|
||||||
int waitingForAnswer;
|
int waitingForAnswer;
|
||||||
void RenderMessageBackground(float y0, int height);
|
|
||||||
int getActivity();
|
int getActivity();
|
||||||
virtual void Update(float dt){};
|
virtual void Update(float dt){};
|
||||||
virtual void Render(){};
|
virtual void Render(){};
|
||||||
|
|||||||
+161
-285
File diff suppressed because it is too large
Load Diff
@@ -20,18 +20,12 @@ using std::string;
|
|||||||
using std::map;
|
using std::map;
|
||||||
|
|
||||||
|
|
||||||
|
//Two stupid variables used to give a hint to the AI:
|
||||||
|
// Should I cast a spell on an ennemy or friendly unit ?
|
||||||
#define BAKA_EFFECT_GOOD 10
|
#define BAKA_EFFECT_GOOD 10
|
||||||
#define BAKA_EFFECT_BAD 11
|
#define BAKA_EFFECT_BAD 11
|
||||||
|
|
||||||
class AbilityFactory{
|
|
||||||
private:
|
|
||||||
int destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury = 0);
|
|
||||||
int destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury = 0);
|
|
||||||
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
|
|
||||||
public:
|
|
||||||
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
|
|
||||||
void addAbilities(int _id, Spell * spell);
|
|
||||||
};
|
|
||||||
|
|
||||||
class MTGAbility: public ActionElement{
|
class MTGAbility: public ActionElement{
|
||||||
protected:
|
protected:
|
||||||
@@ -67,7 +61,7 @@ class TriggeredAbility:public MTGAbility{
|
|||||||
|
|
||||||
|
|
||||||
class ActivatedAbility:public MTGAbility{
|
class ActivatedAbility:public MTGAbility{
|
||||||
public:
|
public:
|
||||||
ManaCost * cost;
|
ManaCost * cost;
|
||||||
int playerturnonly;
|
int playerturnonly;
|
||||||
int needsTapping;
|
int needsTapping;
|
||||||
@@ -80,7 +74,7 @@ class ActivatedAbility:public MTGAbility{
|
|||||||
};
|
};
|
||||||
|
|
||||||
class TargetAbility:public ActivatedAbility{
|
class TargetAbility:public ActivatedAbility{
|
||||||
public:
|
public:
|
||||||
TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
|
TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
|
||||||
TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
|
TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
|
||||||
virtual void Update(float dt);
|
virtual void Update(float dt);
|
||||||
@@ -90,7 +84,7 @@ class TargetAbility:public ActivatedAbility{
|
|||||||
};
|
};
|
||||||
|
|
||||||
class InstantAbility:public MTGAbility{
|
class InstantAbility:public MTGAbility{
|
||||||
public:
|
public:
|
||||||
int init;
|
int init;
|
||||||
virtual void Update(float dt);
|
virtual void Update(float dt);
|
||||||
virtual int testDestroy();
|
virtual int testDestroy();
|
||||||
@@ -101,7 +95,7 @@ class InstantAbility:public MTGAbility{
|
|||||||
|
|
||||||
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
|
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
|
||||||
class ListMaintainerAbility:public MTGAbility{
|
class ListMaintainerAbility:public MTGAbility{
|
||||||
public:
|
public:
|
||||||
map<MTGCardInstance *,bool> cards;
|
map<MTGCardInstance *,bool> cards;
|
||||||
ListMaintainerAbility(int _id):MTGAbility(_id,NULL){};
|
ListMaintainerAbility(int _id):MTGAbility(_id,NULL){};
|
||||||
ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){};
|
ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){};
|
||||||
@@ -113,6 +107,87 @@ class ListMaintainerAbility:public MTGAbility{
|
|||||||
virtual int destroy();
|
virtual int destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* An attempt to globalize triggered abilities as much as possible */
|
||||||
|
class MTGAbilityBasicFeatures{
|
||||||
|
public:
|
||||||
|
Damageable * target;
|
||||||
|
GameObserver * game;
|
||||||
|
MTGCardInstance * source;
|
||||||
|
MTGAbilityBasicFeatures();
|
||||||
|
MTGAbilityBasicFeatures(MTGCardInstance * _source, Damageable * _target = NULL);
|
||||||
|
void init(MTGCardInstance * _source, Damageable * _target = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Trigger:public MTGAbilityBasicFeatures{
|
||||||
|
public:
|
||||||
|
virtual int trigger()=0;
|
||||||
|
virtual int testDestroy(){return 0;};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TriggerAtPhase:public Trigger{
|
||||||
|
public:
|
||||||
|
int currentPhase, newPhase;
|
||||||
|
int phaseId;
|
||||||
|
|
||||||
|
TriggerAtPhase(int _phaseId);
|
||||||
|
|
||||||
|
virtual int trigger();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TriggerNextPhase:public TriggerAtPhase{
|
||||||
|
public:
|
||||||
|
int destroyActivated;
|
||||||
|
TriggerNextPhase(int _phaseId);
|
||||||
|
|
||||||
|
virtual int testDestroy();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TriggeredEvent:public MTGAbilityBasicFeatures{
|
||||||
|
public:
|
||||||
|
virtual int resolve()=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawEvent:public TriggeredEvent{
|
||||||
|
public:
|
||||||
|
Player * player;
|
||||||
|
int nbcards;
|
||||||
|
DrawEvent(Player * _player, int _nbcards);
|
||||||
|
int resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DestroyCondition:public MTGAbilityBasicFeatures{
|
||||||
|
public:
|
||||||
|
virtual int testDestroy();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GenericTriggeredAbility:public TriggeredAbility{
|
||||||
|
public:
|
||||||
|
Trigger * t;
|
||||||
|
TriggeredEvent * te;
|
||||||
|
DestroyCondition * dc;
|
||||||
|
GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc = NULL, Damageable * _target = NULL);
|
||||||
|
virtual int trigger();
|
||||||
|
virtual int resolve();
|
||||||
|
virtual int testDestroy();
|
||||||
|
~GenericTriggeredAbility();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Ability Factory */
|
||||||
|
class AbilityFactory{
|
||||||
|
private:
|
||||||
|
int destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury = 0);
|
||||||
|
int destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury = 0);
|
||||||
|
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
|
||||||
|
Trigger * parseTrigger(string magicText);
|
||||||
|
public:
|
||||||
|
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
|
||||||
|
void addAbilities(int _id, Spell * spell);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#include "MTGCardInstance.h"
|
#include "MTGCardInstance.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -93,50 +93,46 @@ static int _b[7] = {20, 0, 140,15, 50,255,128};
|
|||||||
#define MOUNTAINHOME 33
|
#define MOUNTAINHOME 33
|
||||||
#define SWAMPHOME 34
|
#define SWAMPHOME 34
|
||||||
#define PLAINSHOME 35
|
#define PLAINSHOME 35
|
||||||
#define FLANKING 36
|
|
||||||
#define RAMPAGE1 37
|
|
||||||
|
|
||||||
#define NB_BASIC_ABILITIES 38
|
#define NB_BASIC_ABILITIES 36
|
||||||
|
|
||||||
static const char * MTGBasicAbilities[] = {
|
static const char * MTGBasicAbilities[] = {
|
||||||
"trample",
|
"trample",
|
||||||
"forestwalk",
|
"forestwalk",
|
||||||
"islandwalk",
|
"islandwalk",
|
||||||
"mountainwalk",
|
"mountainwalk",
|
||||||
"swampwalk",
|
"swampwalk",
|
||||||
"plainwalk",
|
"plainwalk",
|
||||||
"flying",
|
"flying",
|
||||||
"first strike",
|
"first strike",
|
||||||
"double strike",
|
"double strike",
|
||||||
"fear",
|
"fear",
|
||||||
"flash",
|
"flash",
|
||||||
"haste",
|
"haste",
|
||||||
"lifelink",
|
"lifelink",
|
||||||
"reach",
|
"reach",
|
||||||
"shroud",
|
"shroud",
|
||||||
"vigilance",
|
"vigilance",
|
||||||
"defender",
|
"defender",
|
||||||
"banding",
|
"banding",
|
||||||
"protection from green",
|
"protection from green",
|
||||||
"protection from blue",
|
"protection from blue",
|
||||||
"protection from red",
|
"protection from red",
|
||||||
"protection from black",
|
"protection from black",
|
||||||
"protection from white",
|
"protection from white",
|
||||||
"unblockable",
|
"unblockable",
|
||||||
"wither",
|
"wither",
|
||||||
"persist",
|
"persist",
|
||||||
"retrace",
|
"retrace",
|
||||||
"exalted",
|
"exalted",
|
||||||
"legendary",
|
"legendary",
|
||||||
"shadow",
|
"shadow",
|
||||||
"reachshadow",
|
"reachshadow",
|
||||||
"foresthome",
|
"foresthome",
|
||||||
"islandhome",
|
"islandhome",
|
||||||
"moutainhome",
|
"moutainhome",
|
||||||
"swamphome",
|
"swamphome",
|
||||||
"plainshome",
|
"plainshome"
|
||||||
"flanking",
|
|
||||||
"rampage",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +148,7 @@ static const char * MTGBasicAbilities[] = {
|
|||||||
|
|
||||||
|
|
||||||
static const char *MTGPhaseNames[] =
|
static const char *MTGPhaseNames[] =
|
||||||
{
|
{
|
||||||
"---",
|
"---",
|
||||||
"Untap",
|
"Untap",
|
||||||
"Upkeep",
|
"Upkeep",
|
||||||
@@ -167,7 +163,25 @@ static const char *MTGPhaseNames[] =
|
|||||||
"End of turn",
|
"End of turn",
|
||||||
"cleanup",
|
"cleanup",
|
||||||
"---"
|
"---"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *MTGPhaseCodeNames[] =
|
||||||
|
{
|
||||||
|
"beginofturn",
|
||||||
|
"untap",
|
||||||
|
"upkeep",
|
||||||
|
"draw",
|
||||||
|
"firstmain",
|
||||||
|
"combatbegins",
|
||||||
|
"attackers",
|
||||||
|
"blockers",
|
||||||
|
"combatdamage",
|
||||||
|
"combatends",
|
||||||
|
"secondmain",
|
||||||
|
"endofturn",
|
||||||
|
"cleanup",
|
||||||
|
"beforenextturn"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,31 +12,6 @@ ActionElement::ActionElement(int id):JGuiObject(id){
|
|||||||
tc = NULL;
|
tc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void ActionElement::RenderMessageBackground(float y0, int _height){
|
|
||||||
float height = _height;
|
|
||||||
PIXEL_TYPE colors_up[] =
|
|
||||||
{
|
|
||||||
ARGB(0,255,255,255),
|
|
||||||
ARGB(0,255,255,255),
|
|
||||||
ARGB(128,255,255,255),
|
|
||||||
ARGB(128,255,255,255)
|
|
||||||
};
|
|
||||||
|
|
||||||
PIXEL_TYPE colors_down[] =
|
|
||||||
{
|
|
||||||
ARGB(128,255,255,255),
|
|
||||||
ARGB(128,255,255,255),
|
|
||||||
ARGB(0,255,255,255),
|
|
||||||
ARGB(0,255,255,255)
|
|
||||||
};
|
|
||||||
|
|
||||||
JRenderer * renderer = JRenderer::GetInstance();
|
|
||||||
renderer->FillRect(0,y0,SCREEN_WIDTH,height/2,colors_up);
|
|
||||||
renderer->FillRect(0,y0+height/2,SCREEN_WIDTH,height/2,colors_down);
|
|
||||||
// mEngine->DrawLine(0,y0,SCREEN_WIDTH,y0,ARGB(128,255,255,255));
|
|
||||||
// mEngine->DrawLine(0,y0+height,SCREEN_WIDTH,y0+height,ARGB(128,255,255,255));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
int ActionElement::getActivity(){
|
int ActionElement::getActivity(){
|
||||||
|
|
||||||
|
|||||||
+155
-115
@@ -50,7 +50,26 @@ int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Some basic functionnalities that can be added automatically in the text file
|
|
||||||
|
Trigger * AbilityFactory::parseTrigger(string magicText){
|
||||||
|
int found = magicText.find("@");
|
||||||
|
if (found == string::npos) return NULL;
|
||||||
|
|
||||||
|
//Next Time...
|
||||||
|
found = magicText.find("next");
|
||||||
|
if (found != string::npos){
|
||||||
|
for (int i = 0; i < NB_MTG_PHASES; i++){
|
||||||
|
found = magicText.find(MTGPhaseCodeNames[i]);
|
||||||
|
if (found != string::npos){
|
||||||
|
return NEW TriggerNextPhase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Some basic functionalities that can be added automatically in the text file
|
||||||
int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
||||||
int dryMode = 0;
|
int dryMode = 0;
|
||||||
if (!spell) dryMode = 1;
|
if (!spell) dryMode = 1;
|
||||||
@@ -60,7 +79,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
if (!target) target = card;
|
if (!target) target = card;
|
||||||
string magicText = card->magicText;
|
string magicText = card->magicText;
|
||||||
if (card->alias && magicText.size() == 0){
|
if (card->alias && magicText.size() == 0){
|
||||||
//An awful way to gat access to the aliasedcard
|
//An awful way to get access to the aliasedcard
|
||||||
magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText;
|
magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText;
|
||||||
}
|
}
|
||||||
string s;
|
string s;
|
||||||
@@ -89,6 +108,13 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
int doTap = 0;
|
int doTap = 0;
|
||||||
string lordType = "";
|
string lordType = "";
|
||||||
|
|
||||||
|
Trigger * trigger = parseTrigger(s);
|
||||||
|
//Dirty way to remove the trigger text (could get in the way)
|
||||||
|
if (trigger){
|
||||||
|
found = s.find(":");
|
||||||
|
s = s.substr(found+1);
|
||||||
|
}
|
||||||
|
|
||||||
//Tap in the cost ?
|
//Tap in the cost ?
|
||||||
if (s.find("{t}") != string::npos) doTap = 1;
|
if (s.find("{t}") != string::npos) doTap = 1;
|
||||||
|
|
||||||
@@ -154,17 +180,6 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
result++;
|
result++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//Tentative Destroyall not working char is not compatible with string variable
|
|
||||||
//found = s.find("destroyall(");
|
|
||||||
//if (found != string::npos){
|
|
||||||
// if (dryMode) return BAKA_EFFECT_GOOD;
|
|
||||||
// unsigned int end = s.find(")", found+11);
|
|
||||||
// if (end != string::npos){
|
|
||||||
// string type = s.substr(found+11,end-found-11).c_str();
|
|
||||||
// destroyAllFromTypeInPlay(type.c_str(), card);
|
|
||||||
// result++;
|
|
||||||
// continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//Regeneration
|
//Regeneration
|
||||||
found = s.find("}:regenerate");
|
found = s.find("}:regenerate");
|
||||||
@@ -211,10 +226,6 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Summon
|
|
||||||
|
|
||||||
//Reveal Take Target and put in in hand (should be also able to target hand since some card needs you to reveal a card in your hand
|
|
||||||
|
|
||||||
//Damage
|
//Damage
|
||||||
found = s.find("damage");
|
found = s.find("damage");
|
||||||
if (found != string::npos){
|
if (found != string::npos){
|
||||||
@@ -266,7 +277,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Draw
|
//Draw
|
||||||
found = s.find("draw");
|
found = s.find("draw:");
|
||||||
if (found != string::npos){
|
if (found != string::npos){
|
||||||
unsigned int start = s.find(":",found);
|
unsigned int start = s.find(":",found);
|
||||||
unsigned int end = s.find(" ",start);
|
unsigned int end = s.find(" ",start);
|
||||||
@@ -278,6 +289,10 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
nbcards = atoi(s.substr(start+1).c_str());
|
nbcards = atoi(s.substr(start+1).c_str());
|
||||||
}
|
}
|
||||||
if (dryMode) return BAKA_EFFECT_GOOD;
|
if (dryMode) return BAKA_EFFECT_GOOD;
|
||||||
|
if (trigger){
|
||||||
|
DrawEvent * action = NEW DrawEvent(card->controller(),nbcards);
|
||||||
|
game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action));
|
||||||
|
}else{
|
||||||
if (tc){
|
if (tc){
|
||||||
//TODO ?
|
//TODO ?
|
||||||
}else{
|
}else{
|
||||||
@@ -288,6 +303,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
|
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
result++;
|
result++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -450,7 +466,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
case 106525: //Ascendant Evincar
|
case 106525: //Ascendant Evincar
|
||||||
{
|
{
|
||||||
game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1));
|
game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1));
|
||||||
game->addObserver(NEW AColorLord(_id, card,0,MTG_COLOR_BLACK,-1,-1));
|
game->addObserver(NEW AColorLord(_id + 1, card,0,MTG_COLOR_BLACK,-1,-1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,6 +991,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
MTGPlayerCards * zones = card->target->controller()->game;
|
MTGPlayerCards * zones = card->target->controller()->game;
|
||||||
zones->putInZone(card->target,zones->inPlay,zones->hand);
|
zones->putInZone(card->target,zones->inPlay,zones->hand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
case 1235: //Aspect of Wolf
|
case 1235: //Aspect of Wolf
|
||||||
{
|
{
|
||||||
@@ -1270,78 +1287,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Addons ICE-AGE Cards
|
||||||
// Addons ALA
|
|
||||||
|
|
||||||
case 175114: // Master of Etherium
|
|
||||||
{
|
|
||||||
game->addObserver(NEW ACreaturePowerToughnessModifierForAllTypeControlled(_id,card,"artifact"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 174989: // Wild Nacatl
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AGenericKirdApe(_id,card,"plains",1,1));
|
|
||||||
game->addObserver(NEW AGenericKirdApe(_id,card,"moutain",1,1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Addons The Dark
|
|
||||||
|
|
||||||
case 1797: //Inferno does 6 damage to all players and all creatures.
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 2 ; i++){
|
|
||||||
game->mLayers->stackLayer()->addDamage(card, game->players[i], 6);
|
|
||||||
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
|
|
||||||
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
|
|
||||||
if (current->isACreature()){
|
|
||||||
game->mLayers->stackLayer()->addDamage(card, current, 6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1773 : //People of the Woods
|
|
||||||
{
|
|
||||||
game->addObserver(NEW APeopleOfTheWoods(_id, card));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1818: //Tivadar's Crusade
|
|
||||||
{
|
|
||||||
destroyAllFromTypeInPlay("goblin", card);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Addons Legends
|
|
||||||
case 1470: //Acid Rain
|
|
||||||
{
|
|
||||||
destroyAllFromTypeInPlay("forest", card);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1427: //Abomination
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AAbomination(_id,card));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1533: //Livingplane
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AConvertLandToCreatures(id, card, "land"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1607: //Divine Offering
|
|
||||||
{
|
|
||||||
card->target->controller()->game->putInGraveyard(card->target);
|
|
||||||
game->currentlyActing()->life+= card->target->getManaCost()->getConvertedCost();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1625: //Lifeblood
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Addons ICE-AGE Cards
|
|
||||||
case 2631: //Jokulhaups
|
case 2631: //Jokulhaups
|
||||||
{
|
{
|
||||||
destroyAllFromTypeInPlay("artifact", card);
|
destroyAllFromTypeInPlay("artifact", card);
|
||||||
@@ -1470,12 +1416,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
if (card->basicAbilities[PLAINSHOME]){
|
if (card->basicAbilities[PLAINSHOME]){
|
||||||
game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains"));
|
game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains"));
|
||||||
}
|
}
|
||||||
// New Abilities Flanking and Rampage
|
|
||||||
|
|
||||||
if (card->basicAbilities [RAMPAGE1]){
|
|
||||||
game->addObserver (NEW ARampageAbility(_id, card, 1, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Instants are put in the graveyard automatically if that's not already done
|
//Instants are put in the graveyard automatically if that's not already done
|
||||||
if (!putSourceInGraveyard){
|
if (!putSourceInGraveyard){
|
||||||
if (card->hasType("instant") || card->hasType("sorcery")){
|
if (card->hasType("instant") || card->hasType("sorcery")){
|
||||||
@@ -1489,13 +1429,13 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){
|
MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){
|
||||||
game = GameObserver::GetInstance();;
|
game = GameObserver::GetInstance();
|
||||||
source = card;
|
source = card;
|
||||||
target = card;
|
target = card;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){
|
MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){
|
||||||
game = GameObserver::GetInstance();;
|
game = GameObserver::GetInstance();
|
||||||
source = _source;
|
source = _source;
|
||||||
target = _target;
|
target = _target;
|
||||||
}
|
}
|
||||||
@@ -1632,44 +1572,44 @@ void TriggeredAbility::Update(float dt){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){
|
InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){
|
||||||
init = 0;
|
init = 0;
|
||||||
for (int i = 0; i < 2; i++){
|
for (int i = 0; i < 2; i++){
|
||||||
if(game->players[i]->game->inPlay->hasCard(source)){
|
if(game->players[i]->game->inPlay->hasCard(source)){
|
||||||
game->players[i]->game->putInGraveyard(source);
|
game->players[i]->game->putInGraveyard(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstantAbility::Update(float dt){
|
void InstantAbility::Update(float dt){
|
||||||
if (!init){
|
if (!init){
|
||||||
init = resolve();
|
init = resolve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){
|
InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){
|
||||||
init = 0;
|
init = 0;
|
||||||
for (int i = 0; i < 2; i++){
|
for (int i = 0; i < 2; i++){
|
||||||
if(game->players[i]->game->inPlay->hasCard(source)){
|
if(game->players[i]->game->inPlay->hasCard(source)){
|
||||||
game->players[i]->game->putInGraveyard(source);
|
game->players[i]->game->putInGraveyard(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Instant abilities last generally until the end of the turn
|
//Instant abilities last generally until the end of the turn
|
||||||
int InstantAbility::testDestroy(){
|
int InstantAbility::testDestroy(){
|
||||||
int newPhase = game->getCurrentGamePhase();
|
int newPhase = game->getCurrentGamePhase();
|
||||||
if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1;
|
if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1;
|
||||||
currentPhase = newPhase;
|
currentPhase = newPhase;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ListMaintainerAbility::Update(float dt){
|
void ListMaintainerAbility::Update(float dt){
|
||||||
map<MTGCardInstance *,bool>::iterator it=cards.begin();
|
map<MTGCardInstance *,bool>::iterator it=cards.begin();
|
||||||
while(it != cards.end()){
|
while(it != cards.end()){
|
||||||
MTGCardInstance * card = (*it).first;
|
MTGCardInstance * card = (*it).first;
|
||||||
@@ -1688,7 +1628,7 @@ void ListMaintainerAbility::Update(float dt){
|
|||||||
}
|
}
|
||||||
if (doDelete || !canBeInList(card)){
|
if (doDelete || !canBeInList(card)){
|
||||||
#if defined (WIN32) || defined (LINUX)
|
#if defined (WIN32) || defined (LINUX)
|
||||||
OutputDebugString("DELETE FRO LISTMAINTAINER\n");
|
OutputDebugString("DELETE FRO LISTMAINTAINER\n");
|
||||||
#endif
|
#endif
|
||||||
cards.erase(card);
|
cards.erase(card);
|
||||||
removed(card);
|
removed(card);
|
||||||
@@ -1709,10 +1649,10 @@ void ListMaintainerAbility::Update(float dt){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Destroy the spell -> remove all targets
|
//Destroy the spell -> remove all targets
|
||||||
int ListMaintainerAbility::destroy(){
|
int ListMaintainerAbility::destroy(){
|
||||||
map<MTGCardInstance *,bool>::iterator it;
|
map<MTGCardInstance *,bool>::iterator it;
|
||||||
|
|
||||||
for ( it=cards.begin() ; it != cards.end(); it++ ){
|
for ( it=cards.begin() ; it != cards.end(); it++ ){
|
||||||
@@ -1720,4 +1660,104 @@ int ListMaintainerAbility::destroy(){
|
|||||||
}
|
}
|
||||||
cards.clear();
|
cards.clear();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* An attempt to globalize triggered abilities as much as possible */
|
||||||
|
|
||||||
|
MTGAbilityBasicFeatures::MTGAbilityBasicFeatures(){
|
||||||
|
game = GameObserver::GetInstance();
|
||||||
|
}
|
||||||
|
MTGAbilityBasicFeatures::MTGAbilityBasicFeatures(MTGCardInstance * _source, Damageable * _target):source(_source),target(_target){
|
||||||
|
if (!target) target = source;
|
||||||
|
game = GameObserver::GetInstance();
|
||||||
|
}
|
||||||
|
void MTGAbilityBasicFeatures::init(MTGCardInstance * _source, Damageable * _target){
|
||||||
|
source = source;
|
||||||
|
target=_target;
|
||||||
|
if (!target) target = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TriggerAtPhase::TriggerAtPhase(int _phaseId):Trigger(),phaseId(_phaseId){
|
||||||
|
currentPhase = game->getCurrentGamePhase();
|
||||||
|
newPhase = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TriggerAtPhase::trigger(){
|
||||||
|
int result = 0;
|
||||||
|
newPhase = game->getCurrentGamePhase();
|
||||||
|
if (currentPhase != newPhase && newPhase == phaseId){
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
currentPhase = newPhase;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerNextPhase::TriggerNextPhase(int _phaseId):TriggerAtPhase(_phaseId){
|
||||||
|
destroyActivated = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TriggerNextPhase::testDestroy(){
|
||||||
|
if (newPhase <= phaseId) destroyActivated = 1;
|
||||||
|
if ( newPhase > phaseId && destroyActivated){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DrawEvent::DrawEvent(Player * _player, int _nbcards):TriggeredEvent(),player(_player),nbcards(_nbcards){
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawEvent::resolve(){
|
||||||
|
game->mLayers->stackLayer()->addDraw(player,nbcards);
|
||||||
|
return nbcards;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DestroyCondition::testDestroy(){
|
||||||
|
if (!game->isInPlay(source)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (target && !game->isInPlay((MTGCardInstance *)target)){
|
||||||
|
source->controller()->game->putInGraveyard(source);//TODO put this in a better place ???
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc , Damageable * _target ): TriggeredAbility(id, _source,_target){
|
||||||
|
if (!target) target = source;
|
||||||
|
t = _t;
|
||||||
|
te = _te;
|
||||||
|
dc = _dc;
|
||||||
|
|
||||||
|
t->init(_source,_target);
|
||||||
|
te->init(_source,_target);
|
||||||
|
if (dc) dc->init(_source,_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GenericTriggeredAbility::trigger(){
|
||||||
|
return t->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GenericTriggeredAbility::resolve(){
|
||||||
|
return te->resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GenericTriggeredAbility::testDestroy(){
|
||||||
|
if (dc) return dc->testDestroy();
|
||||||
|
return t->testDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericTriggeredAbility::~GenericTriggeredAbility(){
|
||||||
|
delete t;
|
||||||
|
delete te;
|
||||||
|
SAFE_DELETE(dc);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user