-Fix for issue 583 (fireball crash)
-- converted an array into a vector to avoid weird edge cases -- fixed bugs with array "backupTargets"
This commit is contained in:
@@ -275,6 +275,7 @@ fault_line.txt
|
|||||||
feral_hydra.txt
|
feral_hydra.txt
|
||||||
fieldmist_borderpost.txt
|
fieldmist_borderpost.txt
|
||||||
fire_tempest.txt
|
fire_tempest.txt
|
||||||
|
fireball_i583.txt
|
||||||
firebreathing.txt
|
firebreathing.txt
|
||||||
fists_of_ironwood.txt
|
fists_of_ironwood.txt
|
||||||
flagstones.txt
|
flagstones.txt
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#Bug: fireball can crash the game if unselecting a target
|
||||||
|
#see http://code.google.com/p/wagic/issues/detail?id=583
|
||||||
|
#Target 8 creatures and remove 1 of them
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
hand:fireball
|
||||||
|
manapool:{7}{R}{R}{R}{R}{R}{R}{R}{R}
|
||||||
|
inplay:raging goblin,Akrasan Squire,Alpha Myr,Ambush Party,Apprentice Wizard,Arbor Elf,Aven Squire,Bay Falcon
|
||||||
|
[PLAYER2]
|
||||||
|
[DO]
|
||||||
|
fireball
|
||||||
|
raging goblin
|
||||||
|
Akrasan Squire
|
||||||
|
Alpha Myr
|
||||||
|
Ambush Party
|
||||||
|
Apprentice Wizard
|
||||||
|
Arbor Elf
|
||||||
|
Aven Squire
|
||||||
|
Bay Falcon
|
||||||
|
Alpha Myr
|
||||||
|
fireball
|
||||||
|
[ASSERT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
graveyard:raging goblin,Akrasan Squire,Ambush Party,Apprentice Wizard,Arbor Elf,Aven Squire,Bay Falcon, Fireball
|
||||||
|
inplay:Alpha Myr
|
||||||
|
[PLAYER2]
|
||||||
|
[END]
|
||||||
@@ -114,7 +114,7 @@ public:
|
|||||||
int typeAsTarget(){return TARGET_CARD;}
|
int typeAsTarget(){return TARGET_CARD;}
|
||||||
const string getDisplayName() const;
|
const string getDisplayName() const;
|
||||||
MTGCardInstance * target;
|
MTGCardInstance * target;
|
||||||
Targetable * backupTargets[MAX_TARGETS];
|
vector<Targetable *> backupTargets;
|
||||||
|
|
||||||
|
|
||||||
//types
|
//types
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public:
|
|||||||
|
|
||||||
virtual int full()
|
virtual int full()
|
||||||
{
|
{
|
||||||
if (maxtargets != -1 && cursor >= maxtargets)
|
if (maxtargets != -1 && ((int) (targets.size())) >= maxtargets)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
;
|
;
|
||||||
virtual int ready()
|
virtual int ready()
|
||||||
{
|
{
|
||||||
return cursor;
|
return (int) (targets.size());
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
virtual ~TargetChooser()
|
virtual ~TargetChooser()
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#ifndef _TARGETSLIST_H_
|
#ifndef _TARGETSLIST_H_
|
||||||
#define _TARGETSLIST_H_
|
#define _TARGETSLIST_H_
|
||||||
|
|
||||||
#define MAX_TARGETS 20
|
|
||||||
|
|
||||||
class Targetable;
|
class Targetable;
|
||||||
class MTGCardInstance;
|
class MTGCardInstance;
|
||||||
class Player;
|
class Player;
|
||||||
@@ -11,13 +9,15 @@ class Spell;
|
|||||||
class Interruptible;
|
class Interruptible;
|
||||||
class Damage;
|
class Damage;
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
class TargetsList
|
class TargetsList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int cursor;
|
|
||||||
TargetsList();
|
TargetsList();
|
||||||
TargetsList(Targetable * _targets[], int nbtargets);
|
TargetsList(Targetable * _targets[], int nbtargets);
|
||||||
Targetable* targets[MAX_TARGETS];
|
vector<Targetable*> targets;
|
||||||
int alreadyHasTarget(Targetable * target);
|
int alreadyHasTarget(Targetable * target);
|
||||||
int removeTarget(Targetable * _card);
|
int removeTarget(Targetable * _card);
|
||||||
int toggleTarget(Targetable * _card);
|
int toggleTarget(Targetable * _card);
|
||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
Targetable * getNextTarget(Targetable * previous = 0, int type = -1);
|
Targetable * getNextTarget(Targetable * previous = 0, int type = -1);
|
||||||
void initTargets()
|
void initTargets()
|
||||||
{
|
{
|
||||||
cursor = 0;
|
targets.clear();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -217,10 +217,12 @@ Interruptible(id), tc(tc), cost(_cost), payResult(payResult)
|
|||||||
mHeight = 40;
|
mHeight = 40;
|
||||||
type = ACTION_SPELL;
|
type = ACTION_SPELL;
|
||||||
from = _source->getCurrentZone();
|
from = _source->getCurrentZone();
|
||||||
for(int i = 0;i < MAX_TARGETS;i++)
|
|
||||||
|
_source->backupTargets.clear();
|
||||||
|
if (tc)
|
||||||
{
|
{
|
||||||
if(tc && tc->targets[i] != NULL)
|
for(size_t i = 0;i < tc->targets.size();i++)
|
||||||
_source->backupTargets[i] = tc->targets[i];
|
_source->backupTargets.push_back(tc->targets[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill information on how the card came into this zone. Right now the quickest way is to do it here, based on how the mana was paid...
|
// fill information on how the card came into this zone. Right now the quickest way is to do it here, based on how the mana was paid...
|
||||||
@@ -360,7 +362,7 @@ int Spell::getNbTargets()
|
|||||||
{
|
{
|
||||||
if (!tc)
|
if (!tc)
|
||||||
return 0;
|
return 0;
|
||||||
return tc->cursor;
|
return (int) (tc->targets.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::Render()
|
void Spell::Render()
|
||||||
|
|||||||
@@ -1762,9 +1762,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
found = s.find("wingame");
|
found = s.find("wingame");
|
||||||
if (found != string::npos)
|
if (found != string::npos)
|
||||||
{
|
{
|
||||||
Damageable * d = NULL;
|
Damageable * d = spell ? spell->getNextDamageableTarget() : NULL;
|
||||||
if (spell)
|
|
||||||
d = spell->getNextDamageableTarget();
|
|
||||||
MTGAbility * a = NEW AAWinGame(id, card, d, NULL, who);
|
MTGAbility * a = NEW AAWinGame(id, card, d, NULL, who);
|
||||||
a->oneShot = 1;
|
a->oneShot = 1;
|
||||||
return a;
|
return a;
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
|||||||
size_t start = attribute.find("share!");
|
size_t start = attribute.find("share!");
|
||||||
size_t end = attribute.rfind("!");
|
size_t end = attribute.rfind("!");
|
||||||
string CDtype = attribute.substr(start + 6,end - start);
|
string CDtype = attribute.substr(start + 6,end - start);
|
||||||
if( card && card->isSpell() && card->backupTargets[0]->typeAsTarget() == TARGET_STACKACTION)
|
if( card && card->isSpell() && card->backupTargets.size() && card->backupTargets[0]->typeAsTarget() == TARGET_STACKACTION)
|
||||||
{
|
{
|
||||||
//spells always store their targets in :targets[]
|
//spells always store their targets in :targets[]
|
||||||
//however they are all erased as the spell resolves
|
//however they are all erased as the spell resolves
|
||||||
@@ -785,7 +785,7 @@ int TargetChooser::ForceTargetListReady()
|
|||||||
|
|
||||||
int TargetChooser::targetsReadyCheck()
|
int TargetChooser::targetsReadyCheck()
|
||||||
{
|
{
|
||||||
if (cursor <= 0)
|
if (!targets.size())
|
||||||
{
|
{
|
||||||
return TARGET_NOK;
|
return TARGET_NOK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,24 +8,19 @@
|
|||||||
|
|
||||||
TargetsList::TargetsList()
|
TargetsList::TargetsList()
|
||||||
{
|
{
|
||||||
cursor = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetsList::TargetsList(Targetable * _targets[], int nbtargets)
|
TargetsList::TargetsList(Targetable * _targets[], int nbtargets)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < nbtargets; i++)
|
for (int i = 0; i < nbtargets; i++)
|
||||||
{
|
targets.push_back(_targets[i]);
|
||||||
targets[i] = _targets[i];
|
|
||||||
}
|
|
||||||
cursor = nbtargets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int TargetsList::addTarget(Targetable * target)
|
int TargetsList::addTarget(Targetable * target)
|
||||||
{
|
{
|
||||||
if (!alreadyHasTarget(target))
|
if (!alreadyHasTarget(target))
|
||||||
{
|
{
|
||||||
targets[cursor] = target;
|
targets.push_back(target);
|
||||||
cursor++;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -34,7 +29,7 @@ int TargetsList::addTarget(Targetable * target)
|
|||||||
|
|
||||||
int TargetsList::alreadyHasTarget(Targetable * target)
|
int TargetsList::alreadyHasTarget(Targetable * target)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cursor; i++)
|
for (size_t i = 0; i < targets.size(); i++)
|
||||||
{
|
{
|
||||||
if (targets[i] == target) return 1;
|
if (targets[i] == target) return 1;
|
||||||
}
|
}
|
||||||
@@ -43,13 +38,12 @@ int TargetsList::alreadyHasTarget(Targetable * target)
|
|||||||
|
|
||||||
int TargetsList::removeTarget(Targetable * target)
|
int TargetsList::removeTarget(Targetable * target)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cursor; i++)
|
for (size_t i = 0; i < targets.size(); i++)
|
||||||
{
|
{
|
||||||
if (targets[i] == target)
|
if (targets[i] == target)
|
||||||
{
|
{
|
||||||
targets[i] = targets[cursor];
|
targets.erase(targets.begin() + i);
|
||||||
targets[cursor] = NULL;
|
return 1;
|
||||||
cursor--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +68,7 @@ Targetable * TargetsList::getNextTarget(Targetable * previous, int type)
|
|||||||
{
|
{
|
||||||
int found = 0;
|
int found = 0;
|
||||||
if (!previous) found = 1;
|
if (!previous) found = 1;
|
||||||
for (int i = 0; i < cursor; i++)
|
for (size_t i = 0; i < targets.size(); i++)
|
||||||
{
|
{
|
||||||
if (found && (type == -1 || targets[i]->typeAsTarget() == type))
|
if (found && (type == -1 || targets[i]->typeAsTarget() == type))
|
||||||
{
|
{
|
||||||
@@ -99,7 +93,7 @@ Interruptible * TargetsList::getNextInterruptible(Interruptible * previous, int
|
|||||||
{
|
{
|
||||||
int found = 0;
|
int found = 0;
|
||||||
if (!previous) found = 1;
|
if (!previous) found = 1;
|
||||||
for (int i = 0; i < cursor; i++)
|
for (size_t i = 0; i < targets.size(); i++)
|
||||||
{
|
{
|
||||||
if (found && targets[i]->typeAsTarget() == TARGET_STACKACTION)
|
if (found && targets[i]->typeAsTarget() == TARGET_STACKACTION)
|
||||||
{
|
{
|
||||||
@@ -131,7 +125,7 @@ Damageable * TargetsList::getNextDamageableTarget(Damageable * previous)
|
|||||||
{
|
{
|
||||||
int found = 0;
|
int found = 0;
|
||||||
if (!previous) found = 1;
|
if (!previous) found = 1;
|
||||||
for (int i = 0; i < cursor; i++)
|
for (size_t i = 0; i < targets.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (targets[i]->typeAsTarget() == TARGET_PLAYER)
|
if (targets[i]->typeAsTarget() == TARGET_PLAYER)
|
||||||
|
|||||||
Reference in New Issue
Block a user