Erwan
- Dragon Whelp bug fix - Rampage bug fix - AI can use mana abilities.
This commit is contained in:
@@ -120,6 +120,7 @@ paralysis2.txt
|
|||||||
persuasion.txt
|
persuasion.txt
|
||||||
plague_rats.txt
|
plague_rats.txt
|
||||||
protomatter_powder.txt
|
protomatter_powder.txt
|
||||||
|
pygmy_troll.txt
|
||||||
pyroclasm.txt
|
pyroclasm.txt
|
||||||
recover.txt
|
recover.txt
|
||||||
resurrection.txt
|
resurrection.txt
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#Testing bug with Rampage
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:pygmy troll,forest
|
||||||
|
[PLAYER2]
|
||||||
|
inplay:grizzly bears,hill giant
|
||||||
|
[DO]
|
||||||
|
forest
|
||||||
|
pygmy troll
|
||||||
|
next
|
||||||
|
#combat begins
|
||||||
|
next
|
||||||
|
#combat attackers
|
||||||
|
pygmy troll
|
||||||
|
next
|
||||||
|
grizzly bears
|
||||||
|
next
|
||||||
|
next
|
||||||
|
eot
|
||||||
|
eot
|
||||||
|
next
|
||||||
|
#upkeep
|
||||||
|
next
|
||||||
|
#draw
|
||||||
|
next
|
||||||
|
#firstmain
|
||||||
|
next
|
||||||
|
#begins
|
||||||
|
next
|
||||||
|
#attackers
|
||||||
|
pygmy troll
|
||||||
|
next
|
||||||
|
#blockers
|
||||||
|
hill giant
|
||||||
|
next
|
||||||
|
#damage
|
||||||
|
next
|
||||||
|
#end
|
||||||
|
[ASSERT]
|
||||||
|
COMBATEND
|
||||||
|
[PLAYER1]
|
||||||
|
graveyard:pygmy troll
|
||||||
|
inplay:forest
|
||||||
|
manapool:{0}
|
||||||
|
[PLAYER2]
|
||||||
|
graveyard:grizzly bears
|
||||||
|
inplay:hill giant
|
||||||
|
[END]
|
||||||
@@ -1024,6 +1024,13 @@ class APowerToughnessModifierUntilEndOfTurn: public ActivatedAbility{
|
|||||||
ability = NEW AInstantPowerToughnessModifierUntilEOT(id,_source,_target,_power,_toughness);
|
ability = NEW AInstantPowerToughnessModifierUntilEOT(id,_source,_target,_power,_toughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Update(float dt){
|
||||||
|
if (newPhase != currentPhase && newPhase ==Constants::MTG_PHASE_AFTER_EOT){
|
||||||
|
counters = 0;
|
||||||
|
}
|
||||||
|
ActivatedAbility::Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
int fireAbility(){
|
int fireAbility(){
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
@@ -3296,7 +3303,8 @@ class AFireball:public InstantAbility{
|
|||||||
AFireball(int _id, MTGCardInstance * card, Spell * spell, int x):InstantAbility(_id, card){
|
AFireball(int _id, MTGCardInstance * card, Spell * spell, int x):InstantAbility(_id, card){
|
||||||
int nbtargets = spell->cursor;
|
int nbtargets = spell->cursor;
|
||||||
int totaldamage = x+1-nbtargets;
|
int totaldamage = x+1-nbtargets;
|
||||||
int individualdamage = totaldamage / nbtargets;
|
int individualdamage = 0;
|
||||||
|
if (nbtargets) individualdamage = totaldamage / nbtargets;
|
||||||
Damageable * _target = spell->getNextDamageableTarget();
|
Damageable * _target = spell->getNextDamageableTarget();
|
||||||
while(_target){
|
while(_target){
|
||||||
game->mLayers->stackLayer()->addDamage(source,_target,individualdamage);
|
game->mLayers->stackLayer()->addDamage(source,_target,individualdamage);
|
||||||
@@ -3890,7 +3898,6 @@ class AMinionofLeshrac: public TargetAbility{
|
|||||||
//Rampage ability
|
//Rampage ability
|
||||||
class ARampageAbility:public MTGAbility{
|
class ARampageAbility:public MTGAbility{
|
||||||
public:
|
public:
|
||||||
MTGCardInstance * opponents[20];
|
|
||||||
int nbOpponents;
|
int nbOpponents;
|
||||||
int PowerModifier;
|
int PowerModifier;
|
||||||
int ToughnessModifier;
|
int ToughnessModifier;
|
||||||
@@ -3899,44 +3906,26 @@ class ARampageAbility:public MTGAbility{
|
|||||||
ARampageAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier, int _MaxOpponent):MTGAbility(_id, _source){
|
ARampageAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier, int _MaxOpponent):MTGAbility(_id, _source){
|
||||||
PowerModifier = _PowerModifier;
|
PowerModifier = _PowerModifier;
|
||||||
ToughnessModifier = _ToughnessModifier;
|
ToughnessModifier = _ToughnessModifier;
|
||||||
MaxOpponent = _MaxOpponent;
|
MaxOpponent = _MaxOpponent;
|
||||||
|
nbOpponents = 0;
|
||||||
}
|
}
|
||||||
void Update(float dt){
|
void Update(float dt){
|
||||||
if (source->isAttacker()){
|
if (newPhase != currentPhase){
|
||||||
if (newPhase != currentPhase){
|
if( source->isAttacker() && newPhase == Constants::MTG_PHASE_COMBATDAMAGE){
|
||||||
if( newPhase == Constants::MTG_PHASE_COMBATDAMAGE){
|
nbOpponents = source->blockers.size();
|
||||||
nbOpponents = 0;
|
for (int i = MaxOpponent; i < nbOpponents; i++){
|
||||||
MTGCardInstance * opponent = source->getNextOpponent();
|
source->power+= PowerModifier;
|
||||||
while (opponent){
|
source->addToToughness(ToughnessModifier);
|
||||||
opponents[nbOpponents] = opponent;
|
}
|
||||||
nbOpponents ++;
|
}
|
||||||
opponent = source->getNextOpponent(opponent);
|
if( newPhase == Constants::MTG_PHASE_AFTER_EOT ){
|
||||||
if (nbOpponents > MaxOpponent){
|
for (int i = MaxOpponent; i < nbOpponents; i++){
|
||||||
source->power+= PowerModifier;
|
source->power-= PowerModifier;
|
||||||
source->addToToughness(ToughnessModifier);
|
source->addToToughness(-ToughnessModifier);
|
||||||
|
}
|
||||||
}
|
nbOpponents = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if( newPhase == Constants::MTG_PHASE_AFTER_EOT ){
|
|
||||||
for (int i = 0; i < nbOpponents; i++){
|
|
||||||
source->power-= PowerModifier;
|
|
||||||
source->addToToughness(-ToughnessModifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "ARampageAbility ::: opponents : " << opponents
|
|
||||||
<< " ; nbOpponents : " << nbOpponents
|
|
||||||
<< " ; PowerModifier : " << PowerModifier
|
|
||||||
<< " ; ToughnessModifier : " << ToughnessModifier
|
|
||||||
<< " ; MaxOpponent : " << MaxOpponent
|
|
||||||
<< " (";
|
|
||||||
return MTGAbility::toString(out) << ")";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ARampageAbility * clone() const{
|
ARampageAbility * clone() const{
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ class AbilityFactory{
|
|||||||
class AManaProducer: public MTGAbility{
|
class AManaProducer: public MTGAbility{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
ManaCost * output;
|
|
||||||
string menutext;
|
string menutext;
|
||||||
float x0,y0,x1,y1,x,y;
|
float x0,y0,x1,y1,x,y;
|
||||||
float animation;
|
float animation;
|
||||||
@@ -226,6 +226,7 @@ class AManaProducer: public MTGAbility{
|
|||||||
|
|
||||||
hgeParticleSystem * mParticleSys;
|
hgeParticleSystem * mParticleSys;
|
||||||
public:
|
public:
|
||||||
|
ManaCost * output;
|
||||||
int tap;
|
int tap;
|
||||||
static int currentlyTapping;
|
static int currentlyTapping;
|
||||||
AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1 );
|
AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1 );
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../include/DamagerDamaged.h"
|
#include "../include/DamagerDamaged.h"
|
||||||
#include "../include/AIStats.h"
|
#include "../include/AIStats.h"
|
||||||
#include "../include/AllAbilities.h"
|
#include "../include/AllAbilities.h"
|
||||||
|
#include "../include/ExtraCost.h"
|
||||||
|
|
||||||
const char * const MTG_LAND_TEXTS[] = {"artifact","forest","island","mountain","swamp","plains","other lands"};
|
const char * const MTG_LAND_TEXTS[] = {"artifact","forest","island","mountain","swamp","plains","other lands"};
|
||||||
|
|
||||||
@@ -68,57 +69,54 @@ void AIPlayer::tapLandsForMana(ManaCost * potentialMana, ManaCost * cost){
|
|||||||
#endif
|
#endif
|
||||||
if (!cost) return;
|
if (!cost) return;
|
||||||
ManaCost * diff = potentialMana->Diff(cost);
|
ManaCost * diff = potentialMana->Diff(cost);
|
||||||
GameObserver * gameObs = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
CardDescriptor cd;
|
|
||||||
cd.setColor(Constants::MTG_COLOR_LAND);
|
|
||||||
cd.unsecureSetTapped(-1);
|
|
||||||
|
|
||||||
MTGCardInstance * card = NULL;
|
map<MTGCardInstance *,bool>used;
|
||||||
while((card = cd.nextmatch(game->inPlay, card))){
|
for (int i = 1; i < g->mLayers->actionLayer()->mCount; i++){ //0 is not a mtgability...hackish
|
||||||
|
//Make sure we can use the ability
|
||||||
int doTap = 1;
|
MTGAbility * a = ((MTGAbility *)g->mLayers->actionLayer()->mObjects[i]);
|
||||||
for (int i=Constants::MTG_NB_COLORS-1; i>= 0; i--){
|
AManaProducer * amp = dynamic_cast<AManaProducer*>(a);
|
||||||
if (diff->getCost(i) && card->hasSubtype(MTG_LAND_TEXTS[i]) ){
|
if (amp){
|
||||||
diff->remove(i,1);
|
MTGCardInstance * card = amp->source;
|
||||||
doTap = 0;
|
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost()==1){
|
||||||
break;
|
int doTap = 1;
|
||||||
|
for (int i=Constants::MTG_NB_COLORS-1; i>= 0; i--){
|
||||||
|
if (diff->getCost(i) && amp->output->getCost(i) ){
|
||||||
|
diff->remove(i,1);
|
||||||
|
doTap = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (doTap){
|
||||||
|
AIAction * action = NEW AIAction(amp,card);
|
||||||
|
clickstream.push(action);
|
||||||
|
used[card] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (doTap){
|
|
||||||
AIAction * a = NEW AIAction(card);
|
|
||||||
clickstream.push(a);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(diff);
|
delete(diff);
|
||||||
|
|
||||||
}
|
}
|
||||||
//TODO a better function that does not take into account only basic lands
|
|
||||||
ManaCost * AIPlayer::getPotentialMana(){
|
ManaCost * AIPlayer::getPotentialMana(){
|
||||||
SAFE_DELETE(potentialMana);
|
SAFE_DELETE(potentialMana);
|
||||||
potentialMana = NEW ManaCost();
|
potentialMana = NEW ManaCost();
|
||||||
CardDescriptor cd;
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
cd.setColor(Constants::MTG_COLOR_LAND);
|
map<MTGCardInstance *,bool>used;
|
||||||
cd.unsecureSetTapped(-1);
|
for (int i = 1; i < g->mLayers->actionLayer()->mCount; i++){ //0 is not a mtgability...hackish
|
||||||
MTGCardInstance * card = NULL;
|
//Make sure we can use the ability
|
||||||
while((card = cd.nextmatch(game->inPlay, card))){
|
MTGAbility * a = ((MTGAbility *)g->mLayers->actionLayer()->mObjects[i]);
|
||||||
|
AManaProducer * amp = dynamic_cast<AManaProducer*>(a);
|
||||||
if (card->hasSubtype("plains")){
|
if (amp){
|
||||||
potentialMana->add(Constants::MTG_COLOR_WHITE,1);
|
MTGCardInstance * card = amp->source;
|
||||||
}else if(card->hasSubtype("swamp")){
|
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost()==1){
|
||||||
potentialMana->add(Constants::MTG_COLOR_BLACK,1);
|
potentialMana->add(amp->output);
|
||||||
}else if(card->hasSubtype("forest")){
|
used[card] = true;
|
||||||
potentialMana->add(Constants::MTG_COLOR_GREEN,1);
|
}
|
||||||
}else if(card->hasSubtype("mountain")){
|
|
||||||
potentialMana->add(Constants::MTG_COLOR_RED,1);
|
|
||||||
}else if(card->hasSubtype("island")){
|
|
||||||
potentialMana->add(Constants::MTG_COLOR_BLUE,1);
|
|
||||||
}else{
|
|
||||||
#if defined (WIN32) || defined (LINUX)
|
|
||||||
OutputDebugString("WTF ????\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return potentialMana;
|
return potentialMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +146,15 @@ int AIAction::getEfficiency(){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Can't handle sacrifice costs that require a target yet :(
|
||||||
|
if (a->cost){
|
||||||
|
ExtraCosts * ec = a->cost->extraCosts;
|
||||||
|
if (ec){
|
||||||
|
for (size_t i = 0; i < ec->costs.size(); i++){
|
||||||
|
if (ec->costs[i]->tc) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (a->aType){
|
switch (a->aType){
|
||||||
case MTGAbility::DAMAGER:
|
case MTGAbility::DAMAGER:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -519,7 +519,12 @@ MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){
|
|||||||
|
|
||||||
int MTGCardInstance::setDefenser(MTGCardInstance * opponent){
|
int MTGCardInstance::setDefenser(MTGCardInstance * opponent){
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
if (defenser) defenser->blockers.remove(this);
|
if (defenser) {
|
||||||
|
if (g->players[0]->game->battlefield->hasCard(defenser) ||
|
||||||
|
g->players[1]->game->battlefield->hasCard(defenser) ) {
|
||||||
|
defenser->blockers.remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
WEvent * e = NEW WEventCreatureBlocker(this, defenser, opponent);
|
WEvent * e = NEW WEventCreatureBlocker(this, defenser, opponent);
|
||||||
defenser = opponent;
|
defenser = opponent;
|
||||||
if (defenser){
|
if (defenser){
|
||||||
|
|||||||
Reference in New Issue
Block a user