- Added "PreventAllCombatDamage" [from(...)] [to(...)] keyword. Please test it on a few cards before we "mass" use it. As a side effect, fixed issue 155 (ebony horse target).
This commit is contained in:
wagic.the.homebrew@gmail.com
2009-11-14 11:35:29 +00:00
parent 5781060d83
commit 9ca552093e
15 changed files with 2695 additions and 2577 deletions

View File

@@ -2147,6 +2147,82 @@ public:
};
class APreventAllCombatDamage:public MTGAbility{
public:
string to, from;
REDamagePrevention * re;
APreventAllCombatDamage(int id,MTGCardInstance * source,string to,string from):MTGAbility(id,source),to(to),from(from){
re = NULL;
}
int addToGame(){
if (re) {
OutputDebugString("FATAL:re shouldn't be already set in APreventAllCombatDAMAGE\n");
return 0;
}
TargetChooserFactory tcf;
TargetChooser *toTc = tcf.createTargetChooser(to,source,this);
if (toTc) toTc->targetter = NULL;
TargetChooser *fromTc = tcf.createTargetChooser(from,source,this);
if (fromTc) fromTc->targetter = NULL;
re = NEW REDamagePrevention (this, fromTc, toTc, -1, false, DAMAGE_COMBAT);
game->replacementEffects->add(re);
return 1;
}
int Destroy(){
game->replacementEffects->remove(re);
delete re;
return 1;
}
APreventAllCombatDamage * clone() const{
APreventAllCombatDamage * a = NEW APreventAllCombatDamage(*this);
a->isClone = 1;
return a;
}
};
//Adds types/abilities/P/T to a card (until end of turn)
class APreventAllCombatDamageUEOT: public InstantAbility{
public:
APreventAllCombatDamage * ability;
APreventAllCombatDamageUEOT(int id,MTGCardInstance * source,string to, string from):InstantAbility(id,source){
ability = NEW APreventAllCombatDamage(id,source,to, from);
}
int resolve(){
ability->target = this->target;
ability->addToGame();
return 1;
}
int destroy(){
ability->destroy();
return 1;
}
const char * getMenuText(){
return ability->getMenuText();
}
APreventAllCombatDamageUEOT * clone() const{
APreventAllCombatDamageUEOT * a = NEW APreventAllCombatDamageUEOT(*this);
a->ability = this->ability->clone();
a->isClone = 1;
return a;
}
~APreventAllCombatDamageUEOT(){
delete ability;
}
};
/*
Specific Classes
*/
@@ -2607,33 +2683,6 @@ class ADisruptingScepter:public TargetAbility{
};
//1108 Ebony Horse
class AEbonyHorse:public TargetAbility{
public:
AEbonyHorse(int _id, MTGCardInstance * _source):TargetAbility(_id,_source, NEW CreatureTargetChooser()){
int _cost[] = {Constants::MTG_COLOR_ARTIFACT, 2};
cost = NEW ManaCost(_cost,1);
}
int resolve(){
MTGCardInstance * _target = tc->getNextCardTarget();
if (_target->isAttacker()) _target->toggleAttacker();
return 1;
}
virtual ostream& toString(ostream& out) const
{
out << "AEbonyHorse ::: (";
return TargetAbility::toString(out) << ")";
}
AEbonyHorse * clone() const{
AEbonyHorse * a = NEW AEbonyHorse(*this);
a->isClone = 1;
return a;
}
};
//1345 Farmstead
class AFarmstead:public ActivatedAbility{
public:

View File

@@ -13,6 +13,10 @@ class GameObserver;
#define DAMAGEABLE_MTGCARDINSTANCE 0
#define DAMAGEABLE_PLAYER 1
#define DAMAGE_ALL_TYPES 0
#define DAMAGE_COMBAT 1
#define DAMAGE_OTHER 2
class Damageable:public Targetable {
protected:
@@ -28,13 +32,14 @@ class Damageable:public Targetable {
class Damage: public Interruptible {
protected:
void init(MTGCardInstance * source, Damageable * target, int damage);
void init(MTGCardInstance * source, Damageable * target, int damage, int typeOfDamage);
public:
Damageable * target;
int typeOfDamage;
int damage;
void Render();
Damage(MTGCardInstance* source, Damageable * target);
Damage(MTGCardInstance* source, Damageable * target, int damage);
Damage(MTGCardInstance* source, Damageable * target, int damage, int typeOfDamage = DAMAGE_OTHER);
int resolve();
virtual ostream& toString(ostream& out) const;
};

View File

@@ -1,249 +1,249 @@
#ifndef _MTGABILITY_H_
#define _MTGABILITY_H_
class MTGCardInstance;
class GameObserver;
class Spell;
class Damageable;
class PlayGuiObject;
class ManaCost;
class MTGGameZone;
class Player;
class AManaProducer;
class WEvent;
#include "ActionElement.h"
#include <string>
#include <map>
#include <hge/hgeparticle.h>
#include "../include/Damage.h"
#include "../include/TargetChooser.h"
using std::string;
using std::map;
//stupid variables used to give a hint to the AI:
// Should I cast a spell on an enemy or friendly unit ?
#define BAKA_EFFECT_GOOD 1
#define BAKA_EFFECT_BAD -1
#define BAKA_EFFECT_DONTKNOW 0
#define MODE_PUTINTOPLAY 1
#define MODE_ABILITY 2
#define MODE_TARGET 3
#define COUNT_POWER 1
#define PARSER_LORD 1
#define PARSER_FOREACH 2
#define PARSER_ASLONGAS 3
class MTGAbility: public ActionElement{
protected:
char menuText[25];
GameObserver * game;
public:
int oneShot;
int forceDestroy;
ManaCost * cost;
Targetable * target;
int aType;
MTGCardInstance * source;
MTGAbility(int id, MTGCardInstance * card);
MTGAbility(int id, MTGCardInstance * _source, Targetable * _target);
virtual int testDestroy();
virtual ~MTGAbility();
virtual void Render(){};
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){return 0;};
virtual int reactToClick(MTGCardInstance * card){return 0;};
virtual int receiveEvent(WEvent * event){return 0;};
virtual void Update(float dt){};
virtual int fireAbility();
virtual int stillInUse(MTGCardInstance * card);
virtual int resolve(){return 0;};
virtual MTGAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
virtual int addToGame();
virtual int removeFromGame();
/*Poor man's casting */
/* Todo replace that crap with dynamic casting */
enum {
UNKNOWN = 0,
MANA_PRODUCER = 1,
MTG_ATTACK_RULE = 2,
DAMAGER = 3,
STANDARD_REGENERATE = 4,
PUT_INTO_PLAY = 5,
MOMIR = 6,
MTG_BLOCK_RULE = 7,
};
};
class TriggeredAbility:public MTGAbility{
public:
TriggeredAbility(int id, MTGCardInstance * card);
TriggeredAbility(int id, MTGCardInstance * _source, Targetable * _target);
virtual void Update(float dt);
virtual void Render(){};
virtual int trigger(){return 0;};
virtual int triggerOnEvent(WEvent * e){return 0;};
int receiveEvent(WEvent * e);
virtual int resolve() = 0;
virtual TriggeredAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
class ActivatedAbility:public MTGAbility{
public:
int playerturnonly;
int needsTapping;
ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
virtual int reactToClick(MTGCardInstance * card);
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
virtual int reactToTargetClick(Targetable * object);
virtual int resolve() = 0;
virtual ActivatedAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
class TargetAbility:public ActivatedAbility{
public:
MTGAbility * ability;
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);
virtual int reactToClick(MTGCardInstance * card);
virtual int reactToTargetClick(Targetable * object);
virtual TargetAbility* clone() const = 0;
virtual void Render();
virtual int resolve();
virtual const char * getMenuText();
virtual ostream& toString(ostream& out) const;
~TargetAbility();
};
class InstantAbility:public MTGAbility{
public:
int init;
virtual void Update(float dt);
virtual int testDestroy();
InstantAbility(int _id, MTGCardInstance * source);
InstantAbility(int _id, MTGCardInstance * source,Damageable * _target);
virtual int resolve(){return 0;};
virtual InstantAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
class ListMaintainerAbility:public MTGAbility{
public:
map<MTGCardInstance *,bool> cards;
map<Player *,bool> players;
ListMaintainerAbility(int _id):MTGAbility(_id,NULL){};
ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){};
ListMaintainerAbility(int _id, MTGCardInstance *_source,Damageable * _target):MTGAbility(_id, _source, _target){};
virtual void Update(float dt);
void updateTargets();
virtual bool canTarget(MTGGameZone * zone);
virtual int canBeInList(MTGCardInstance * card) = 0;
virtual int added(MTGCardInstance * card) = 0;
virtual int removed(MTGCardInstance * card) = 0;
virtual int canBeInList(Player * p){return 0;};
virtual int added(Player * p){return 0;};
virtual int removed(Player * p){return 0;};
virtual int destroy();
virtual ListMaintainerAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
class TriggerAtPhase:public TriggeredAbility{
public:
int phaseId;
int who;
TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0);
virtual int trigger();
int resolve(){return 0;};
virtual TriggerAtPhase* clone() const;
};
class TriggerNextPhase:public TriggerAtPhase{
public:
int destroyActivated;
TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0);
virtual TriggerNextPhase* clone() const;
virtual int testDestroy();
};
class GenericTriggeredAbility:public TriggeredAbility{
public:
TriggeredAbility * t;
MTGAbility * ability;
MTGAbility * destroyCondition;
GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,MTGAbility * dc = NULL, Targetable * _target = NULL);
virtual int trigger();
virtual int triggerOnEvent(WEvent * e);
virtual int resolve();
virtual int testDestroy();
void Update(float dt);
virtual GenericTriggeredAbility* clone() const;
const char * getMenuText();
~GenericTriggeredAbility();
};
/* Ability Factory */
class AbilityFactory{
private:
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
int parsePowerToughness(string s, int *power, int *toughness);
TriggeredAbility * parseTrigger(string s, int id, Spell * spell, MTGCardInstance *card, Targetable * target);
public:
MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0, int forceUEOT = 0);
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY, TargetChooser * tc = NULL);
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
static int computeX(Spell * spell, MTGCardInstance * card);
int destroyAllInPlay(TargetChooser * tc, int bury = 0);
int moveAll(TargetChooser * tc, string destinationZone);
int damageAll(TargetChooser * tc, int damage);
int TapAll(TargetChooser * tc);
int CantBlock(TargetChooser * tc);
int UntapAll(TargetChooser * tc);
void addAbilities(int _id, Spell * spell);
};
#ifndef _MTGABILITY_H_
#define _MTGABILITY_H_
class MTGCardInstance;
class GameObserver;
class Spell;
class Damageable;
class PlayGuiObject;
class ManaCost;
class MTGGameZone;
class Player;
class AManaProducer;
class WEvent;
#include "ActionElement.h"
#include <string>
#include <map>
#include <hge/hgeparticle.h>
#include "../include/Damage.h"
#include "../include/TargetChooser.h"
using std::string;
using std::map;
//stupid variables used to give a hint to the AI:
// Should I cast a spell on an enemy or friendly unit ?
#define BAKA_EFFECT_GOOD 1
#define BAKA_EFFECT_BAD -1
#define BAKA_EFFECT_DONTKNOW 0
#define MODE_PUTINTOPLAY 1
#define MODE_ABILITY 2
#define MODE_TARGET 3
#define COUNT_POWER 1
#define PARSER_LORD 1
#define PARSER_FOREACH 2
#define PARSER_ASLONGAS 3
class MTGAbility: public ActionElement{
protected:
char menuText[25];
GameObserver * game;
public:
int oneShot;
int forceDestroy;
ManaCost * cost;
Targetable * target;
int aType;
MTGCardInstance * source;
MTGAbility(int id, MTGCardInstance * card);
MTGAbility(int id, MTGCardInstance * _source, Targetable * _target);
virtual int testDestroy();
virtual ~MTGAbility();
virtual void Render(){};
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){return 0;};
virtual int reactToClick(MTGCardInstance * card){return 0;};
virtual int receiveEvent(WEvent * event){return 0;};
virtual void Update(float dt){};
virtual int fireAbility();
virtual int stillInUse(MTGCardInstance * card);
virtual int resolve(){return 0;};
virtual MTGAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
virtual int addToGame();
virtual int removeFromGame();
/*Poor man's casting */
/* Todo replace that crap with dynamic casting */
enum {
UNKNOWN = 0,
MANA_PRODUCER = 1,
MTG_ATTACK_RULE = 2,
DAMAGER = 3,
STANDARD_REGENERATE = 4,
PUT_INTO_PLAY = 5,
MOMIR = 6,
MTG_BLOCK_RULE = 7,
};
};
class TriggeredAbility:public MTGAbility{
public:
TriggeredAbility(int id, MTGCardInstance * card);
TriggeredAbility(int id, MTGCardInstance * _source, Targetable * _target);
virtual void Update(float dt);
virtual void Render(){};
virtual int trigger(){return 0;};
virtual int triggerOnEvent(WEvent * e){return 0;};
int receiveEvent(WEvent * e);
virtual int resolve() = 0;
virtual TriggeredAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
class ActivatedAbility:public MTGAbility{
public:
int playerturnonly;
int needsTapping;
ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
virtual int reactToClick(MTGCardInstance * card);
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
virtual int reactToTargetClick(Targetable * object);
virtual int resolve() = 0;
virtual ActivatedAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
class TargetAbility:public ActivatedAbility{
public:
MTGAbility * ability;
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);
virtual int reactToClick(MTGCardInstance * card);
virtual int reactToTargetClick(Targetable * object);
virtual TargetAbility* clone() const = 0;
virtual void Render();
virtual int resolve();
virtual const char * getMenuText();
virtual ostream& toString(ostream& out) const;
~TargetAbility();
};
class InstantAbility:public MTGAbility{
public:
int init;
virtual void Update(float dt);
virtual int testDestroy();
InstantAbility(int _id, MTGCardInstance * source);
InstantAbility(int _id, MTGCardInstance * source,Damageable * _target);
virtual int resolve(){return 0;};
virtual InstantAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
class ListMaintainerAbility:public MTGAbility{
public:
map<MTGCardInstance *,bool> cards;
map<Player *,bool> players;
ListMaintainerAbility(int _id):MTGAbility(_id,NULL){};
ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){};
ListMaintainerAbility(int _id, MTGCardInstance *_source,Damageable * _target):MTGAbility(_id, _source, _target){};
virtual void Update(float dt);
void updateTargets();
virtual bool canTarget(MTGGameZone * zone);
virtual int canBeInList(MTGCardInstance * card) = 0;
virtual int added(MTGCardInstance * card) = 0;
virtual int removed(MTGCardInstance * card) = 0;
virtual int canBeInList(Player * p){return 0;};
virtual int added(Player * p){return 0;};
virtual int removed(Player * p){return 0;};
virtual int destroy();
virtual ListMaintainerAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const;
};
class TriggerAtPhase:public TriggeredAbility{
public:
int phaseId;
int who;
TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0);
virtual int trigger();
int resolve(){return 0;};
virtual TriggerAtPhase* clone() const;
};
class TriggerNextPhase:public TriggerAtPhase{
public:
int destroyActivated;
TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0);
virtual TriggerNextPhase* clone() const;
virtual int testDestroy();
};
class GenericTriggeredAbility:public TriggeredAbility{
public:
TriggeredAbility * t;
MTGAbility * ability;
MTGAbility * destroyCondition;
GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,MTGAbility * dc = NULL, Targetable * _target = NULL);
virtual int trigger();
virtual int triggerOnEvent(WEvent * e);
virtual int resolve();
virtual int testDestroy();
void Update(float dt);
virtual GenericTriggeredAbility* clone() const;
const char * getMenuText();
~GenericTriggeredAbility();
};
/* Ability Factory */
class AbilityFactory{
private:
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
int parsePowerToughness(string s, int *power, int *toughness);
TriggeredAbility * parseTrigger(string s, int id, Spell * spell, MTGCardInstance *card, Targetable * target);
public:
MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0, int forceUEOT = 0);
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY, TargetChooser * tc = NULL);
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
static int computeX(Spell * spell, MTGCardInstance * card);
int destroyAllInPlay(TargetChooser * tc, int bury = 0);
int moveAll(TargetChooser * tc, string destinationZone);
int damageAll(TargetChooser * tc, int damage);
int TapAll(TargetChooser * tc);
int CantBlock(TargetChooser * tc);
int UntapAll(TargetChooser * tc);
void addAbilities(int _id, Spell * spell);
};
class ActivatedAbilityTP:public ActivatedAbility{
public:
int who;
ActivatedAbilityTP(int id, MTGCardInstance * card, Targetable * _target = NULL, ManaCost * cost=NULL, int doTap = 0, int who = TargetChooser::UNSET);
Targetable * getTarget();
};
class AManaProducer: public ActivatedAbilityTP{
protected:
string menutext;
Player * controller;
public:
ManaCost * output;
int tap;
AManaProducer(int id, MTGCardInstance * card, Targetable * t, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1, int who = TargetChooser::UNSET );
int isReactingToClick(MTGCardInstance * _card, ManaCost * mana = NULL);
int resolve();
int reactToClick(MTGCardInstance * _card);
const char * getMenuText();
~AManaProducer();
virtual AManaProducer * clone() const;
};
#include "MTGCardInstance.h"
#endif
};
class AManaProducer: public ActivatedAbilityTP{
protected:
string menutext;
Player * controller;
public:
ManaCost * output;
int tap;
AManaProducer(int id, MTGCardInstance * card, Targetable * t, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1, int who = TargetChooser::UNSET );
int isReactingToClick(MTGCardInstance * _card, ManaCost * mana = NULL);
int resolve();
int reactToClick(MTGCardInstance * _card);
const char * getMenuText();
~AManaProducer();
virtual AManaProducer * clone() const;
};
#include "MTGCardInstance.h"
#endif

View File

@@ -24,7 +24,7 @@ class PlayGuiObject: public JGuiObject, public JGuiListener, public Pos{
float defaultHeight;
bool mHasFocus;
int type;
virtual void Entering(){mHasFocus = true; zoom = 1.4;};
virtual void Entering(){mHasFocus = true; zoom = 1.4f;};
virtual bool Leaving(u32 key){mHasFocus = false; zoom = 1.0; return true;};
virtual bool CheckUserInput(u32 key) {return false;};
virtual bool ButtonPressed(){return true;};

View File

@@ -3,6 +3,7 @@
#include <list>
using namespace std;
#include "../include/Damage.h"
#include "WEvent.h"
class TargetChooser;
@@ -21,8 +22,9 @@ protected:
TargetChooser * tcTarget;
int damage;
bool oneShot;
int typeOfDamage;
public:
REDamagePrevention(MTGAbility * _source, TargetChooser *_tcSource = NULL,TargetChooser *_tcTarget = NULL, int _damage = -1, bool _oneShot = true);
REDamagePrevention(MTGAbility * _source, TargetChooser *_tcSource = NULL,TargetChooser *_tcTarget = NULL, int _damage = -1, bool _oneShot = true, int typeOfDamage = DAMAGE_ALL_TYPES);
WEvent * replace (WEvent *e);
~REDamagePrevention();
};

View File

@@ -58,7 +58,7 @@ class TargetChooser: public TargetsList {
class TargetChooserFactory{
public:
TargetChooser * createTargetChooser(string s, MTGCardInstance * card);
TargetChooser * createTargetChooser(string s, MTGCardInstance * card, MTGAbility * ability = NULL);
TargetChooser * createTargetChooser(MTGCardInstance * card);
};