Erwan
- Added WEvent class, allows to send events to abilities - Cards that change zones now becomes new objects (as specified in the Comprehensive rules). This should allow to fix lots of stupid bugs in the near future, but probably brings loads of new issues :(
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
class MTGCardInstance;
|
||||
class Targetable;
|
||||
class TargetChooser;
|
||||
class WEvent;
|
||||
|
||||
class ActionElement: public JGuiObject{
|
||||
protected:
|
||||
@@ -39,6 +40,8 @@ class ActionElement: public JGuiObject{
|
||||
virtual int isReactingToTargetClick(Targetable * card);
|
||||
virtual int reactToTargetClick(Targetable * card);
|
||||
virtual int isReactingToClick(MTGCardInstance * card){return 0;};
|
||||
virtual int stillInUse(MTGCardInstance * card){return 0;};
|
||||
virtual int receiveEvent(WEvent * event){return 0;};
|
||||
virtual int reactToClick(MTGCardInstance * card){return 0;};
|
||||
virtual const char * getMenuText(){return "Ability";};
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
class GuiLayer;
|
||||
class Targetable;
|
||||
class WEvent;
|
||||
|
||||
class ActionLayer: public GuiLayer, public JGuiListener{
|
||||
public:
|
||||
@@ -22,12 +23,14 @@ class ActionLayer: public GuiLayer, public JGuiListener{
|
||||
virtual void Update(float dt);
|
||||
int unstopableRenderInProgress();
|
||||
bool CheckUserInput(u32 key);
|
||||
ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL;};
|
||||
ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL;};
|
||||
int isWaitingForAnswer();
|
||||
int isReactingToTargetClick(Targetable * card);
|
||||
int receiveEvent(WEvent * event);
|
||||
int reactToTargetClick(Targetable * card);
|
||||
int isReactingToClick(MTGCardInstance * card);
|
||||
int reactToClick(MTGCardInstance * card);
|
||||
int stillInUse(MTGCardInstance * card);
|
||||
void setMenuObject(Targetable * object);
|
||||
void ButtonPressed(int controllerid, int controlid);
|
||||
void doReactTo(int menuIndex);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "CardGui.h"
|
||||
#include "GameOptions.h"
|
||||
#include "Token.h"
|
||||
#include "WEvent.h"
|
||||
|
||||
#include <JGui.h>
|
||||
#include <hge/hgeparticle.h>
|
||||
@@ -169,10 +170,11 @@ public:
|
||||
}
|
||||
for ( it=abilities.begin() ; it != abilities.end(); it++ ){
|
||||
myToken->basicAbilities[*it] = 1;
|
||||
}
|
||||
}
|
||||
source->controller()->game->stack->addCard(myToken);
|
||||
Spell * spell = NEW Spell(myToken);
|
||||
|
||||
source->controller()->game->stack->addCard(myToken);
|
||||
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
return 1;
|
||||
@@ -201,8 +203,9 @@ public:
|
||||
//inplay is a special zone !
|
||||
for (int i=0; i < 2; i++){
|
||||
if (destZone == game->players[i]->game->inPlay){
|
||||
Spell * spell = NEW Spell(_target);
|
||||
game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->stack);
|
||||
MTGCardInstance * copy = game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->stack);
|
||||
Spell * spell = NEW Spell(copy);
|
||||
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
return 1;
|
||||
@@ -1201,9 +1204,9 @@ class AAladdinsLamp: public TargetAbility{
|
||||
int fireAbility(){
|
||||
source->tapped = 1;
|
||||
MTGLibrary * library = game->currentlyActing()->game->library;
|
||||
library->removeCard(tc->getNextCardTarget());
|
||||
MTGCardInstance * card = library->removeCard(tc->getNextCardTarget());
|
||||
library->shuffleTopToBottom(nbcards - 1 );
|
||||
library->addCard(tc->getNextCardTarget());
|
||||
library->addCard(card);
|
||||
init = 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -1442,41 +1445,39 @@ class AConservator: public MTGAbility{
|
||||
|
||||
|
||||
//Creature bond
|
||||
class ACreatureBond:public TriggeredAbility{
|
||||
class ACreatureBond:public MTGAbility{
|
||||
public:
|
||||
int mTriggered;
|
||||
int resolved;
|
||||
ACreatureBond(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id,_source,_target){
|
||||
mTriggered = 0;
|
||||
ACreatureBond(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id,_source,_target){
|
||||
resolved = 0;
|
||||
}
|
||||
|
||||
int trigger(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
for (int i = 0; i < 2; i++){
|
||||
if (!mTriggered && game->players[i]->game->graveyard->hasCard(_target)){
|
||||
mTriggered = 1;
|
||||
return 1;
|
||||
int receiveEvent(WEvent * event){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if (event->type == WEvent::CHANGE_ZONE){
|
||||
WEventZoneChange * e = (WEventZoneChange *) event;
|
||||
MTGCardInstance * card = e->card->previous;
|
||||
if (card == _target){
|
||||
for (int i = 0; i < 2 ; i++){
|
||||
Player * p = game->players[i];
|
||||
if (e->to == p->game->graveyard){
|
||||
game->mLayers->stackLayer()->addDamage(source,_target->controller(),_target->toughness);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
game->mLayers->stackLayer()->addDamage(source,_target->controller(),_target->toughness);
|
||||
resolved = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int testDestroy(){
|
||||
/* int testDestroy(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||
if(_target->controller()->game->graveyard->hasCard(_target) && !resolved){
|
||||
return 0;
|
||||
}else{
|
||||
return TriggeredAbility::testDestroy();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
//1105: Dingus Egg
|
||||
@@ -1733,10 +1734,12 @@ class AAnimateDead:public MTGAbility{
|
||||
card->life = card->toughness;
|
||||
//Put the card in play again, with all its abilities !
|
||||
//AbilityFactory af;
|
||||
Spell * spell = NEW Spell(card);
|
||||
MTGCardInstance * copy = source->controller()->game->putInZone(card, _target->controller()->game->graveyard, source->controller()->game->stack);
|
||||
Spell * spell = NEW Spell(copy);
|
||||
//af.addAbilities(game->mLayers->actionLayer()->getMaxId(), spell);
|
||||
source->controller()->game->putInZone(card, _target->controller()->game->graveyard, source->controller()->game->stack);
|
||||
|
||||
spell->resolve();
|
||||
target = spell->source;
|
||||
delete spell;
|
||||
}
|
||||
|
||||
@@ -1893,14 +1896,14 @@ class AKudzu: public TargetAbility{
|
||||
|
||||
void Update(float dt){
|
||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||
if (!_target->tapped){
|
||||
if (_target && !_target->tapped){
|
||||
previouslyTapped = 0;
|
||||
}else if (!previouslyTapped){
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
OutputDebugString("Kudzu Strikes !\n");
|
||||
#endif
|
||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||
_target->controller()->game->putInGraveyard(_target);
|
||||
target = _target->controller()->game->putInGraveyard(_target);
|
||||
reactToClick(source); // ????
|
||||
}
|
||||
TargetAbility::Update(dt);
|
||||
@@ -1922,7 +1925,7 @@ class AKudzu: public TargetAbility{
|
||||
target = tc->getNextCardTarget();
|
||||
source->target = (MTGCardInstance *) target;
|
||||
previouslyTapped = 0;
|
||||
if (source->target->tapped) previouslyTapped = 1;
|
||||
if (source->target && source->target->tapped) previouslyTapped = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class Counters{
|
||||
Counter * hasCounter(const char * _name,int _power = 0, int _toughness = 0);
|
||||
Counter * hasCounter(int _power, int _toughness);
|
||||
Counter * getNext(Counter * previous = NULL);
|
||||
int init();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ class ManaCost;
|
||||
class MTGGameZone;
|
||||
class Player;
|
||||
class AManaProducer;
|
||||
class WEvent;
|
||||
|
||||
#include "ActionElement.h"
|
||||
#include <string>
|
||||
@@ -33,9 +34,10 @@ using std::map;
|
||||
class MTGAbility: public ActionElement{
|
||||
protected:
|
||||
char menuText[25];
|
||||
Damageable * target;
|
||||
|
||||
GameObserver * game;
|
||||
public:
|
||||
Damageable * target;
|
||||
MTGCardInstance * source;
|
||||
MTGAbility(int id, MTGCardInstance * card);
|
||||
MTGAbility(int id, MTGCardInstance * _source, Damageable * _target);
|
||||
@@ -44,8 +46,10 @@ class MTGAbility: public ActionElement{
|
||||
virtual void Render(){};
|
||||
virtual int isReactingToClick(MTGCardInstance * card){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){if (card==source) return 1; return 0;};
|
||||
virtual int resolve(){return 0;};
|
||||
|
||||
|
||||
|
||||
@@ -38,8 +38,12 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable {
|
||||
void initMTGCI();
|
||||
public:
|
||||
bool isToken;
|
||||
int stillInUse();
|
||||
Player * lastController;
|
||||
MTGGameZone * getCurrentZone();
|
||||
MTGGameZone * previousZone;
|
||||
MTGCardInstance * previous;
|
||||
MTGCardInstance * next;
|
||||
int doDamageTest;
|
||||
int summoningSickness;
|
||||
// The recommended method to test for summoning Sickness !
|
||||
|
||||
@@ -15,8 +15,9 @@ class Player;
|
||||
|
||||
class MTGGameZone {
|
||||
protected:
|
||||
Player * owner;
|
||||
|
||||
public:
|
||||
Player * owner;
|
||||
//Both cards and cardsMap contain the cards of a zone. The long term objective is to get rid of the array
|
||||
MTGCardInstance * cards[MTG_MAX_PLAYER_CARDS];
|
||||
map<MTGCardInstance *,int> cardsMap;
|
||||
@@ -93,9 +94,9 @@ class MTGPlayerCards {
|
||||
void discardRandom(MTGGameZone * from);
|
||||
void drawFromLibrary();
|
||||
void showHand();
|
||||
void putInGraveyard(MTGCardInstance * card);
|
||||
void putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
||||
void putInPlay(MTGCardInstance * card);
|
||||
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
|
||||
MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
||||
MTGCardInstance * putInPlay(MTGCardInstance * card);
|
||||
int isInPlay(MTGCardInstance * card);
|
||||
|
||||
};
|
||||
|
||||
@@ -49,6 +49,7 @@ class MTGGuiPlay: public PlayGuiObjectController {
|
||||
void Update(float dt);
|
||||
bool CheckUserInput(u32 key);
|
||||
virtual void Render();
|
||||
void forceUpdateCards();
|
||||
void updateCards();
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "../include/MTGAbility.h"
|
||||
#include "../include/Counters.h"
|
||||
|
||||
#include "../include/WEvent.h"
|
||||
|
||||
class MTGPutInPlayRule:public MTGAbility{
|
||||
public:
|
||||
@@ -39,6 +39,49 @@ class MTGBlockRule:public MTGAbility{
|
||||
|
||||
|
||||
/* Persist Rule */
|
||||
class MTGPersistRule:public MTGAbility{
|
||||
public:
|
||||
MTGPersistRule(int _id):MTGAbility(_id,NULL){};
|
||||
|
||||
int receiveEvent(WEvent * event){
|
||||
OutputDebugString("Receive1\n");
|
||||
if (event->type == WEvent::CHANGE_ZONE){
|
||||
OutputDebugString("Receive2\n");
|
||||
WEventZoneChange * e = (WEventZoneChange *) event;
|
||||
MTGCardInstance * card = e->card->previous;
|
||||
if (card && card->basicAbilities[Constants::PERSIST] && !card->counters->hasCounter(-1,-1)){
|
||||
OutputDebugString("Receive3\n");
|
||||
int ok = 0;
|
||||
for (int i = 0; i < 2 ; i++){
|
||||
Player * p = game->players[i];
|
||||
if (e->from == p->game->inPlay) ok = 1;
|
||||
}
|
||||
if (!ok) return 0;
|
||||
OutputDebugString("Receive4\n");
|
||||
for (int i = 0; i < 2 ; i++){
|
||||
Player * p = game->players[i];
|
||||
if (e->to == p->game->graveyard){
|
||||
OutputDebugString("Receive5\n");
|
||||
//p->game->putInZone(card, p->game->graveyard, card->owner->game->hand);
|
||||
MTGCardInstance * copy = p->game->putInZone(e->card, p->game->graveyard, e->card->owner->game->stack);
|
||||
Spell * spell = NEW Spell(copy);
|
||||
spell->resolve();
|
||||
spell->source->counters->addCounter(-1,-1);
|
||||
game->mLayers->playLayer()->forceUpdateCards();
|
||||
delete spell;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDestroy(){return 0;}
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
class MTGPersistRule:public ListMaintainerAbility{
|
||||
public:
|
||||
MTGPersistRule(int _id):ListMaintainerAbility(_id){};
|
||||
@@ -50,23 +93,29 @@ class MTGPersistRule:public ListMaintainerAbility{
|
||||
MTGCardInstance * card = ((*it).first);
|
||||
Player * p = card->controller();
|
||||
if (p->game->graveyard->hasCard(card)){
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
OutputDebugString("persist passed test 1 !\n");
|
||||
#endif
|
||||
p->game->putInZone(card, p->game->graveyard, p->game->hand);
|
||||
Spell * spell = NEW Spell(card);
|
||||
p->game->putInZone(card, p->game->hand, p->game->stack);
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
OutputDebugString("persist passed test 2 !\n");
|
||||
#endif
|
||||
card->counters->addCounter(-1,-1);
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
OutputDebugString("persist passed test 3 !\n");
|
||||
#endif
|
||||
p->game->putInZone(card, p->game->graveyard, p->game->hand);
|
||||
Spell * spell = NEW Spell(card);
|
||||
p->game->putInZone(card, p->game->hand, p->game->stack);
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
card->counters->addCounter(-1,-1);
|
||||
}
|
||||
}
|
||||
|
||||
// Dirtiest Code Ever, we remove the counters here
|
||||
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = game->players[i];
|
||||
MTGGameZone * zones[] = {p->game->graveyard, p->game->hand, p->game->library, p->game->removedFromGame};
|
||||
for (int j = 0; j < 5; j++){
|
||||
MTGGameZone * zone = zones[j];
|
||||
for (int k=0; k < zone->nb_cards; k++){
|
||||
zone->cards[k]->counters->init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ListMaintainerAbility::Update(dt);
|
||||
}
|
||||
|
||||
@@ -87,7 +136,7 @@ class MTGPersistRule:public ListMaintainerAbility{
|
||||
int testDestroy(){return 0;}
|
||||
};
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Rule 420.5e (Legend Rule)
|
||||
|
||||
24
projects/mtg/include/WEvent.h
Normal file
24
projects/mtg/include/WEvent.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _WEVENT_H_
|
||||
#define _WEVENT_H_
|
||||
|
||||
class MTGCardInstance;
|
||||
class MTGGameZone;
|
||||
|
||||
class WEvent{
|
||||
public:
|
||||
enum{
|
||||
CHANGE_ZONE = 1,
|
||||
};
|
||||
int type;
|
||||
WEvent(int _type);
|
||||
};
|
||||
|
||||
class WEventZoneChange: public WEvent{
|
||||
public:
|
||||
MTGCardInstance * card;
|
||||
MTGGameZone * from;
|
||||
MTGGameZone * to;
|
||||
WEventZoneChange(MTGCardInstance * _card, MTGGameZone * _from, MTGGameZone *_to);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user