- Dragon Whelp bug fix
- Rampage bug fix
- AI can use mana abilities.
This commit is contained in:
wagic.the.homebrew@gmail.com
2009-07-19 04:19:24 +00:00
parent 72e10fab24
commit 9b263eaee1
6 changed files with 130 additions and 78 deletions
+1
View File
@@ -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
+49
View File
@@ -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]
+15 -26
View File
@@ -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;
@@ -3900,44 +3907,26 @@ class ARampageAbility:public MTGAbility{
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( newPhase == Constants::MTG_PHASE_COMBATDAMAGE){ if( source->isAttacker() && newPhase == Constants::MTG_PHASE_COMBATDAMAGE){
nbOpponents = 0; nbOpponents = source->blockers.size();
MTGCardInstance * opponent = source->getNextOpponent(); for (int i = MaxOpponent; i < nbOpponents; i++){
while (opponent){
opponents[nbOpponents] = opponent;
nbOpponents ++;
opponent = source->getNextOpponent(opponent);
if (nbOpponents > MaxOpponent){
source->power+= PowerModifier; source->power+= PowerModifier;
source->addToToughness(ToughnessModifier); source->addToToughness(ToughnessModifier);
}
} }
} }
if( newPhase == Constants::MTG_PHASE_AFTER_EOT ){ if( newPhase == Constants::MTG_PHASE_AFTER_EOT ){
for (int i = 0; i < nbOpponents; i++){ for (int i = MaxOpponent; i < nbOpponents; i++){
source->power-= PowerModifier; source->power-= PowerModifier;
source->addToToughness(-ToughnessModifier); source->addToToughness(-ToughnessModifier);
} }
nbOpponents = 0;
} }
} }
} }
}
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{
ARampageAbility * a = NEW ARampageAbility(*this); ARampageAbility * a = NEW ARampageAbility(*this);
+2 -1
View File
@@ -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 );
+40 -33
View File
@@ -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;
while((card = cd.nextmatch(game->inPlay, card))){
map<MTGCardInstance *,bool>used;
for (int i = 1; i < g->mLayers->actionLayer()->mCount; i++){ //0 is not a mtgability...hackish
//Make sure we can use the ability
MTGAbility * a = ((MTGAbility *)g->mLayers->actionLayer()->mObjects[i]);
AManaProducer * amp = dynamic_cast<AManaProducer*>(a);
if (amp){
MTGCardInstance * card = amp->source;
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost()==1){
int doTap = 1; int doTap = 1;
for (int i=Constants::MTG_NB_COLORS-1; i>= 0; i--){ for (int i=Constants::MTG_NB_COLORS-1; i>= 0; i--){
if (diff->getCost(i) && card->hasSubtype(MTG_LAND_TEXTS[i]) ){ if (diff->getCost(i) && amp->output->getCost(i) ){
diff->remove(i,1); diff->remove(i,1);
doTap = 0; doTap = 0;
break; break;
} }
} }
if (doTap){ if (doTap){
AIAction * a = NEW AIAction(card); AIAction * action = NEW AIAction(amp,card);
clickstream.push(a); clickstream.push(action);
used[card] = true;
}
}
} }
} }
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 (amp){
MTGCardInstance * card = amp->source;
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost()==1){
potentialMana->add(amp->output);
used[card] = true;
}
}
}
if (card->hasSubtype("plains")){
potentialMana->add(Constants::MTG_COLOR_WHITE,1);
}else if(card->hasSubtype("swamp")){
potentialMana->add(Constants::MTG_COLOR_BLACK,1);
}else if(card->hasSubtype("forest")){
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:
{ {
+6 -1
View File
@@ -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){