Erwan
- Added name effect for Momir - Fixed a couple bugs with "moveTo", see test/Amugaba.txt
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
#text=Flying. {2}{U}, Discard a card from your hand: Return Amugaba to its owner's hand.
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
hand:swamp
|
||||||
|
inplay:Amugaba
|
||||||
|
manapool:{2}{U}
|
||||||
|
[PLAYER2]
|
||||||
|
[DO]
|
||||||
|
Amugaba
|
||||||
|
Swamp
|
||||||
|
[ASSERT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
hand:Amugaba
|
||||||
|
graveyard:Swamp
|
||||||
|
manapool:{0}
|
||||||
|
[PLAYER2]
|
||||||
|
[END]
|
||||||
@@ -18,6 +18,7 @@ generic/wither.txt
|
|||||||
#Specific Cards
|
#Specific Cards
|
||||||
########################
|
########################
|
||||||
afflict.txt
|
afflict.txt
|
||||||
|
Amugaba.txt
|
||||||
anarchy.txt
|
anarchy.txt
|
||||||
animate_dead.txt
|
animate_dead.txt
|
||||||
animate_dead2.txt
|
animate_dead2.txt
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class AIPlayer: public Player{
|
|||||||
int interruptIfICan();
|
int interruptIfICan();
|
||||||
int chooseAttackers();
|
int chooseAttackers();
|
||||||
int chooseBlockers();
|
int chooseBlockers();
|
||||||
|
int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
|
||||||
int effectBadOrGood(MTGCardInstance * card);
|
int effectBadOrGood(MTGCardInstance * card);
|
||||||
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
|
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
|
||||||
AIStats * getStats();
|
AIStats * getStats();
|
||||||
|
|||||||
@@ -270,6 +270,45 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//Moves Cards from a zone to another
|
||||||
|
//TODO: this looks awfully similar to the equivalent targetAbility...woudln't there be a way to merge them ?
|
||||||
|
class AZoneSelfMover:public ActivatedAbility{
|
||||||
|
|
||||||
|
public:
|
||||||
|
string destinationZone;
|
||||||
|
|
||||||
|
AZoneSelfMover(int _id, MTGCardInstance * _source,string destZone, ManaCost * _cost = NULL, int _tap=0):ActivatedAbility(_id,_source,_cost,0,_tap){
|
||||||
|
destinationZone = destZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolve(){
|
||||||
|
MTGCardInstance * _target = source;
|
||||||
|
if(_target){
|
||||||
|
Player* p = _target->controller();
|
||||||
|
if (p){
|
||||||
|
MTGGameZone * fromZone = _target->getCurrentZone();
|
||||||
|
MTGGameZone * destZone = MTGGameZone::stringToZone(destinationZone, source,_target);
|
||||||
|
//inplay is a special zone !
|
||||||
|
for (int i=0; i < 2; i++){
|
||||||
|
if (destZone == game->players[i]->game->inPlay){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->game->putInZone(_target,fromZone,destZone);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//Copier. TargetAbility
|
//Copier. TargetAbility
|
||||||
class ACopier:public TargetAbility{
|
class ACopier:public TargetAbility{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -127,6 +127,9 @@ private:
|
|||||||
int genRandomCreatureId(int convertedCost);
|
int genRandomCreatureId(int convertedCost);
|
||||||
static vector<int> pool[20];
|
static vector<int> pool[20];
|
||||||
static int initialized;
|
static int initialized;
|
||||||
|
|
||||||
|
int textAlpha;
|
||||||
|
string text;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int alreadyplayed;
|
int alreadyplayed;
|
||||||
@@ -134,6 +137,7 @@ public:
|
|||||||
MTGCardInstance * genCreature(int id);
|
MTGCardInstance * genCreature(int id);
|
||||||
int testDestroy();
|
int testDestroy();
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
|
void Render();
|
||||||
MTGMomirRule(int _id, MTGAllCards * _collection);
|
MTGMomirRule(int _id, MTGAllCards * _collection);
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||||
int reactToClick(MTGCardInstance * card);
|
int reactToClick(MTGCardInstance * card);
|
||||||
|
|||||||
@@ -396,6 +396,14 @@ int AIPlayer::chooseAttackers(){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Can I first strike my oponent and get away with murder ? */
|
||||||
|
int AIPlayer::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy){
|
||||||
|
if (ennemy->has(Constants::FIRSTSTRIKE) || ennemy->has(Constants::DOUBLESTRIKE)) return 0;
|
||||||
|
if (!(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE))) return 0;
|
||||||
|
if (!card->power >= ennemy->toughness) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int AIPlayer::chooseBlockers(){
|
int AIPlayer::chooseBlockers(){
|
||||||
map<MTGCardInstance *, int> opponentsToughness;
|
map<MTGCardInstance *, int> opponentsToughness;
|
||||||
int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER);
|
int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER);
|
||||||
@@ -408,9 +416,10 @@ int AIPlayer::chooseBlockers(){
|
|||||||
cd.tapped = -1;
|
cd.tapped = -1;
|
||||||
MTGCardInstance * card = NULL;
|
MTGCardInstance * card = NULL;
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
|
MTGAbility * a = g->mLayers->actionLayer()->getAbility(MTGAbility::MTG_BLOCK_RULE);
|
||||||
|
|
||||||
while((card = cd.nextmatch(game->inPlay, card))){
|
while((card = cd.nextmatch(game->inPlay, card))){
|
||||||
g->cardClick(card);
|
g->mLayers->actionLayer()->reactToClick(a,card);
|
||||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
|
||||||
int set = 0;
|
int set = 0;
|
||||||
while(!set){
|
while(!set){
|
||||||
if (!card->defenser){
|
if (!card->defenser){
|
||||||
@@ -426,8 +435,7 @@ int AIPlayer::chooseBlockers(){
|
|||||||
opponentsToughness[attacker]-= card->power;
|
opponentsToughness[attacker]-= card->power;
|
||||||
set = 1;
|
set = 1;
|
||||||
}else{
|
}else{
|
||||||
g->cardClick(card);
|
g->mLayers->actionLayer()->reactToClick(a,card);
|
||||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -437,25 +445,24 @@ int AIPlayer::chooseBlockers(){
|
|||||||
if (card->defenser && opponentsToughness[card->defenser] > 0){
|
if (card->defenser && opponentsToughness[card->defenser] > 0){
|
||||||
while (card->defenser){
|
while (card->defenser){
|
||||||
|
|
||||||
g->cardClick(card);
|
g->mLayers->actionLayer()->reactToClick(a,card);
|
||||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
card = NULL;
|
card = NULL;
|
||||||
while((card = cd.nextmatch(game->inPlay, card))){
|
while((card = cd.nextmatch(game->inPlay, card))){
|
||||||
if(!card->defenser){
|
if(!card->defenser){
|
||||||
g->cardClick(card);
|
g->mLayers->actionLayer()->reactToClick(a,card);
|
||||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
|
||||||
int set = 0;
|
int set = 0;
|
||||||
while(!set){
|
while(!set){
|
||||||
if (!card->defenser){
|
if (!card->defenser){
|
||||||
set = 1;
|
set = 1;
|
||||||
}else{
|
}else{
|
||||||
MTGCardInstance * attacker = card->defenser;
|
MTGCardInstance * attacker = card->defenser;
|
||||||
if (opponentsToughness[attacker] <= 0 || (card->toughness <= card->defenser->power && opponentForce*2 <life) || card->defenser->nbOpponents()>1){
|
if (opponentsToughness[attacker] <= 0 ||
|
||||||
g->cardClick(card);
|
(card->toughness <= card->defenser->power && opponentForce*2 <life && !canFirstStrikeKill(card,card->defenser)) ||
|
||||||
if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0);
|
card->defenser->nbOpponents()>1){
|
||||||
|
g->mLayers->actionLayer()->reactToClick(a,card);
|
||||||
}else{
|
}else{
|
||||||
set = 1;
|
set = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -429,6 +429,7 @@ void GameStateDuel::Render()
|
|||||||
}
|
}
|
||||||
sprintf(buffer, "Player %i wins (%i)", winner, p0life );
|
sprintf(buffer, "Player %i wins (%i)", winner, p0life );
|
||||||
}
|
}
|
||||||
|
mFont->SetScale(1);
|
||||||
mFont->DrawString(buffer, 10, 150);
|
mFont->DrawString(buffer, 10, 150);
|
||||||
if (unlockedQuad){
|
if (unlockedQuad){
|
||||||
r->RenderQuad(unlockedQuad, 20, 20);
|
r->RenderQuad(unlockedQuad, 20, 20);
|
||||||
|
|||||||
@@ -310,25 +310,32 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
|
|||||||
//MoveTo Move a card from a zone to another
|
//MoveTo Move a card from a zone to another
|
||||||
found = s.find("moveto(");
|
found = s.find("moveto(");
|
||||||
if (found != string::npos){
|
if (found != string::npos){
|
||||||
OutputDebugString("may!\n");
|
|
||||||
if (dryMode) return BAKA_EFFECT_BAD; //TODO : depends on where from, where to...
|
if (dryMode) return BAKA_EFFECT_BAD; //TODO : depends on where from, where to...
|
||||||
int end = s.find(")");
|
int end = s.find(")",found+1);
|
||||||
string szone = s.substr(found + 7,end - found - 7);
|
string szone = s.substr(found + 7,end - found - 7);
|
||||||
if (tc){
|
if (tc){
|
||||||
//if (cost){
|
//if (cost){
|
||||||
AZoneMover * a = NEW AZoneMover(id,card,tc,szone,cost,doTap);
|
AZoneMover * a = NEW AZoneMover(id,card,tc,szone,cost,doTap);
|
||||||
if (may){
|
if (may){
|
||||||
game->addObserver(NEW MayAbility(id,a,card));
|
game->addObserver(NEW MayAbility(id,a,card));
|
||||||
OutputDebugString("may!\n");
|
|
||||||
}else{
|
}else{
|
||||||
game->addObserver(a);
|
game->addObserver(a);
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
}else{
|
||||||
|
if (cost){
|
||||||
|
MTGAbility * a = NEW AZoneSelfMover(id,card,szone,cost,doTap);
|
||||||
|
if (may){
|
||||||
|
game->addObserver(NEW MayAbility(id,a,card));
|
||||||
|
}else{
|
||||||
|
game->addObserver(a);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
MTGGameZone * fromZone = target->getCurrentZone();//this is technically incorrect. The initial zone should be as described in the targetchooser
|
MTGGameZone * fromZone = target->getCurrentZone();//this is technically incorrect. The initial zone should be as described in the targetchooser
|
||||||
MTGGameZone * destZone = MTGGameZone::stringToZone(szone, card, target);
|
MTGGameZone * destZone = MTGGameZone::stringToZone(szone, card, target);
|
||||||
target->controller()->game->putInZone(target,fromZone,destZone);
|
target->controller()->game->putInZone(target,fromZone,destZone);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
result++;
|
result++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){
|
|||||||
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){
|
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){
|
||||||
MTGCardInstance * copy = NULL;
|
MTGCardInstance * copy = NULL;
|
||||||
GameObserver *g = GameObserver::GetInstance();
|
GameObserver *g = GameObserver::GetInstance();
|
||||||
|
if (!from || !to) return card; //Error check
|
||||||
|
|
||||||
if (copy = from->removeCard(card)){
|
if (copy = from->removeCard(card)){
|
||||||
|
|
||||||
@@ -145,6 +146,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
|||||||
delete e;
|
delete e;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
return card; //Error
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTGPlayerCards::discardRandom(MTGGameZone * from){
|
void MTGPlayerCards::discardRandom(MTGGameZone * from){
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ MTGMomirRule::MTGMomirRule(int _id, MTGAllCards * _collection):MTGAbility(_id, N
|
|||||||
}
|
}
|
||||||
alreadyplayed = 0;
|
alreadyplayed = 0;
|
||||||
aType=MTGAbility::MOMIR;
|
aType=MTGAbility::MOMIR;
|
||||||
|
textAlpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MTGMomirRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
int MTGMomirRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
||||||
@@ -211,6 +212,8 @@ int MTGMomirRule::reactToClick(MTGCardInstance * card_to_discard, int cardId){
|
|||||||
spell->source->isToken = 1;
|
spell->source->isToken = 1;
|
||||||
delete spell;
|
delete spell;
|
||||||
alreadyplayed = 1;
|
alreadyplayed = 1;
|
||||||
|
textAlpha = 255;
|
||||||
|
text = card->name;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,5 +241,17 @@ void MTGMomirRule::Update(float dt){
|
|||||||
if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){
|
if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){
|
||||||
alreadyplayed = 0;
|
alreadyplayed = 0;
|
||||||
}
|
}
|
||||||
|
if (textAlpha){
|
||||||
|
textAlpha -= (200*dt);
|
||||||
|
if (textAlpha <0) textAlpha = 0;
|
||||||
|
}
|
||||||
MTGAbility::Update(dt);
|
MTGAbility::Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MTGMomirRule::Render(){
|
||||||
|
if (!textAlpha) return;
|
||||||
|
JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT);
|
||||||
|
mFont->SetScale(2 - (float)textAlpha/130);
|
||||||
|
mFont->SetColor(ARGB(textAlpha,255,255,255));
|
||||||
|
mFont->DrawString(text.c_str(),SCREEN_WIDTH/2,SCREEN_HEIGHT/2,JGETEXT_CENTER);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user