- Add a simple macro system for auto lines (the goal is to help mostly with repetitive card auto lines such as the ones we have in MotD mod) Check the MotD mod for examples.

-- I added an AbilityParser.cpp file, mid term goal is to move AbilityFactory there, so that MTGAbility.cpp becomes a bit less big.
-- I tried to add the file reference in Makefiles, but only tested windows compilation so far
- Fixed bugs related to "castRestriction" variables in MTGAbility. these variables were declared in both the parent and children classes, leading to bugs and duplicate code/content

The test suite passes
This commit is contained in:
wagic.the.homebrew
2011-10-15 16:19:29 +00:00
parent 28069e980b
commit 6825082d6d
16 changed files with 201 additions and 24 deletions

View File

@@ -28,6 +28,7 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/$(PNG_PATH) \
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.cpp \
$(MTG_PATH)/src/AbilityParser.cpp \
$(MTG_PATH)/src/ActionElement.cpp \
$(MTG_PATH)/src/ActionLayer.cpp \
$(MTG_PATH)/src/ActionStack.cpp \

View File

@@ -1,4 +1,4 @@
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIHints.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIPlayerBaka.o objs/AIStats.o objs/AllAbilities.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/CardSelectorSingleton.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckEditorMenu.o objs/DeckMenu.o objs/DeckMenuItem.o objs/DeckMetaData.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/DeckManager.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GameStateStory.o objs/GameStateTransitions.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/IconButton.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/ModRules.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGPack.o objs/MTGRules.o objs/Navigator.o objs/ObjectAnalytics.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PlayRestrictions.o objs/Pos.o objs/PrecompiledHeader.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/SimplePopup.o objs/StoryFlow.o objs/StyleManager.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o objs/WFont.o
OBJS = objs/AbilityParser.o objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIHints.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIPlayerBaka.o objs/AIStats.o objs/AllAbilities.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/CardSelectorSingleton.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckEditorMenu.o objs/DeckMenu.o objs/DeckMenuItem.o objs/DeckMetaData.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/DeckManager.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GameStateStory.o objs/GameStateTransitions.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/IconButton.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/ModRules.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGPack.o objs/MTGRules.o objs/Navigator.o objs/ObjectAnalytics.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PlayRestrictions.o objs/Pos.o objs/PrecompiledHeader.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/SimplePopup.o objs/StoryFlow.o objs/StyleManager.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o objs/WFont.o
DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)

View File

@@ -3026,21 +3026,22 @@ toughness=6
name=Archery Training
target=creature
auto=@each my upkeep:may counter(0/0,1,Archery) all(this)
auto=this(counter{0/0.1.Archery}=) teach(creature) {T}:damage:1 target(creature[attacking;blocking])
auto=this(counter{0/0.2.Archery}=) teach(creature) {T}:damage:2 target(creature[attacking;blocking])
auto=this(counter{0/0.3.Archery}=) teach(creature) {T}:damage:3 target(creature[attacking;blocking])
auto=this(counter{0/0.4.Archery}=) teach(creature) {T}:damage:4 target(creature[attacking;blocking])
auto=this(counter{0/0.5.Archery}=) teach(creature) {T}:damage:5 target(creature[attacking;blocking])
auto=this(counter{0/0.6.Archery}=) teach(creature) {T}:damage:6 target(creature[attacking;blocking])
auto=this(counter{0/0.7.Archery}=) teach(creature) {T}:damage:7 target(creature[attacking;blocking])
auto=this(counter{0/0.8.Archery}=) teach(creature) {T}:damage:8 target(creature[attacking;blocking])
auto=this(counter{0/0.9.Archery}=) teach(creature) {T}:damage:9 target(creature[attacking;blocking])
auto=this(counter{0/0.10.Archery}=) teach(creature) {T}:damage:10 target(creature[attacking;blocking])
auto=this(counter{0/0.11.Archery}=) teach(creature) {T}:damage:11 target(creature[attacking;blocking])
auto=this(counter{0/0.12.Archery}=) teach(creature) {T}:damage:12 target(creature[attacking;blocking])
auto=this(counter{0/0.13.Archery}=) teach(creature) {T}:damage:13 target(creature[attacking;blocking])
auto=this(counter{0/0.14.Archery}=) teach(creature) {T}:damage:14 target(creature[attacking;blocking])
auto=this(counter{0/0.15.Archery}=) teach(creature) {T}:damage:15 target(creature[attacking;blocking])
#AUTO_DEFINE _ARCHERY_TRAINING_($c) this(counter{0/0.$c.Archery}=) teach(creature) {T}:damage:$c target(creature[attacking;blocking])
auto=_ARCHERY_TRAINING_(1)
auto=_ARCHERY_TRAINING_(2)
auto=_ARCHERY_TRAINING_(3)
auto=_ARCHERY_TRAINING_(4)
auto=_ARCHERY_TRAINING_(5)
auto=_ARCHERY_TRAINING_(6)
auto=_ARCHERY_TRAINING_(7)
auto=_ARCHERY_TRAINING_(8)
auto=_ARCHERY_TRAINING_(9)
auto=_ARCHERY_TRAINING_(10)
auto=_ARCHERY_TRAINING_(11)
auto=_ARCHERY_TRAINING_(12)
auto=_ARCHERY_TRAINING_(13)
auto=_ARCHERY_TRAINING_(14)
auto=_ARCHERY_TRAINING_(15)
text=Enchant creature -- At the beginning of your upkeep, you may put an arrow counter on Archery Training. -- Enchanted creature has "{T}: This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on Archery Training."
mana={W}
type=Enchantment

View File

@@ -0,0 +1,26 @@
#ifndef _ABILITY_PARSER_H_
#define _ABILITY_PARSER_H_
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::map;
class AutoLineMacro {
private:
string mName;
string mResult;
vector<string> mParams;
void parse(string& s);
string process(string& s);
static vector<AutoLineMacro *> gAutoLineMacros;
static map<string, bool> gAutoLineMacrosIndex;
public:
AutoLineMacro(string& s);
static void Destroy();
static bool AddMacro(string& s);
static string Process(string& s);
};
#endif

View File

@@ -946,7 +946,6 @@ class GenericActivatedAbility: public ActivatedAbility, public NestedAbility
public:
MTGGameZone * activeZone;
string newName;
string castRestriction;
GenericActivatedAbility(GameObserver* observer, string newName,string castRestriction,int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "",
int restrictions = 0, MTGGameZone * dest = NULL);
@@ -1059,7 +1058,6 @@ public:
int counters;
MTGGameZone * activeZone;
string newName;
string castRestriction;
GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "", int restrictions = 0, MTGGameZone * dest = NULL);
const char * getMenuText();

View File

@@ -0,0 +1,126 @@
#include "PrecompiledHeader.h"
#include "AbilityParser.h"
#include "utils.h"
#include <boost/algorithm/string.hpp>
using std::string;
using std::vector;
vector<AutoLineMacro *> AutoLineMacro::gAutoLineMacros;
map<string, bool> AutoLineMacro::gAutoLineMacrosIndex;
AutoLineMacro::AutoLineMacro(string& s)
{
parse(s);
}
void AutoLineMacro::parse(string& s)
{
//we convert to lower, because the counterpart (auto strings) is converted to lower at parse time
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
size_t firstSpace = s.find(" ");
if (firstSpace == string::npos)
{
DebugTrace("FATAL:error parsing macro : " << s);
return;
}
size_t firstParenthesis = s.find("(");
if (firstParenthesis != string::npos && firstParenthesis < firstSpace)
{
//The string has params
mName = s.substr(0, firstParenthesis);
size_t firstClosingParenthesis = s.find(")");
string params = s.substr(firstParenthesis + 1,firstClosingParenthesis - (firstParenthesis + 1));
mParams = split(params, ',');
mResult = s.substr(firstClosingParenthesis + 2);
}
else
{
//no params
mName = s.substr(0, firstSpace);
mResult = s.substr(firstSpace + 1);
}
boost::replace_all(mResult, "\\n", "\n");
}
string AutoLineMacro::process(string& s)
{
string temp = s;
if (!mParams.size())
{
//no params, simple macro
boost::replace_all(temp, mName, mResult);
return temp;
}
//params, complex macro
string toFind = mName + "(";
string result;
size_t occurence = temp.find(toFind);
if (occurence == string::npos)
return s;
while (occurence != string::npos)
{
result.append(temp.substr(0, occurence));
size_t closingParenthesis = temp.find(")");
size_t paramsStart = occurence + toFind.length();
string params = temp.substr(paramsStart, closingParenthesis - paramsStart);
vector<string> vParams = split(params, ',');
if (vParams.size() != mParams.size())
{
return s;
}
string tempResult = mResult;
for (size_t i = 0; i < vParams.size(); ++i)
{
boost::replace_all(tempResult, mParams[i], vParams[i]);
}
result.append(tempResult);
temp = temp.substr(closingParenthesis + 1);
occurence = temp.find(toFind);
}
result.append(temp);
return result;
}
bool AutoLineMacro::AddMacro(string& s)
{
AutoLineMacro * alm = NEW AutoLineMacro(s);
if (gAutoLineMacrosIndex[alm->mName])
{
DebugTrace("WARNING, Macro already exists: " << alm->mName);
delete alm;
return false;
}
gAutoLineMacrosIndex[alm->mName] = true;
gAutoLineMacros.push_back(alm);
return true;
}
void AutoLineMacro::Destroy()
{
for (size_t i = 0; i < gAutoLineMacros.size(); ++i)
{
SAFE_DELETE(gAutoLineMacros[i]);
}
}
string AutoLineMacro::Process(string& s)
{
string result = s;
for (size_t i = 0; i < gAutoLineMacros.size(); ++i)
{
result = gAutoLineMacros[i]->process(result);
}
return result;
}

View File

@@ -8,7 +8,7 @@
//Generic Activated Abilities
GenericActivatedAbility::GenericActivatedAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost,
string limit,MTGAbility * sideEffects,string usesBeforeSideEffects, int restrictions, MTGGameZone * dest) :
ActivatedAbility(observer, _id, card, _cost, restrictions,limit,sideEffects,usesBeforeSideEffects,castRestriction), NestedAbility(a), activeZone(dest),newName(newName),castRestriction(castRestriction)
ActivatedAbility(observer, _id, card, _cost, restrictions,limit,sideEffects,usesBeforeSideEffects,castRestriction), NestedAbility(a), activeZone(dest),newName(newName)
{
counters = 0;
target = ability->target;
@@ -2488,7 +2488,7 @@ MultiAbility::~MultiAbility()
//Generic Target Ability
GenericTargetAbility::GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a,
ManaCost * _cost, string limit,MTGAbility * sideEffects,string usesBeforeSideEffects, int restrictions, MTGGameZone * dest) :
TargetAbility(observer, _id, _source, _tc, _cost, restrictions,castRestriction), limit(limit), activeZone(dest),newName(newName),castRestriction(castRestriction)
TargetAbility(observer, _id, _source, _tc, _cost, restrictions, castRestriction), limit(limit), activeZone(dest),newName(newName)
{
ability = a;
MTGAbility * core = AbilityFactory::getCoreAbility(a);

View File

@@ -30,6 +30,7 @@
#include "ModRules.h"
#include "JFileSystem.h"
#include "Credits.h"
#include "AbilityParser.h"
#define DEFAULT_DURATION .25
@@ -328,6 +329,8 @@ void GameApp::Destroy()
options.theGame = NULL;
Unlockable::Destroy();
AutoLineMacro::Destroy();
Rules::unloadAllRules();
LOG("==Destroying GameApp Successful==");

View File

@@ -12,6 +12,7 @@
#include "ThisDescriptor.h"
#include "ExtraCost.h"
#include "MTGRules.h"
#include "AbilityParser.h"
//Used for Lord/This parsing
@@ -2777,6 +2778,9 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
size_t found;
int result = id;
magicText = AutoLineMacro::Process(magicText);
while (magicText.size())
{
found = magicText.find("\n");
@@ -3891,13 +3895,13 @@ ostream& ActivatedAbility::toString(ostream& out) const
}
TargetAbility::TargetAbility(GameObserver* observer, int id, MTGCardInstance * card, TargetChooser * _tc, ManaCost * _cost, int _playerturnonly, string castRestriction) :
ActivatedAbility(observer, id, card, _cost, _playerturnonly, castRestriction), NestedAbility(NULL)
ActivatedAbility(observer, id, card, _cost, _playerturnonly, "", NULL, "", castRestriction), NestedAbility(NULL) //Todo fix this mess, why do we have to pass "", NULL, "" here before cast restrictions?
{
tc = _tc;
}
TargetAbility::TargetAbility(GameObserver* observer, int id, MTGCardInstance * card, ManaCost * _cost, int _playerturnonly, string castRestriction) :
ActivatedAbility(observer, id, card, _cost, _playerturnonly, castRestriction), NestedAbility(NULL)
ActivatedAbility(observer, id, card, _cost, _playerturnonly, "", NULL, "", castRestriction), NestedAbility(NULL) //Todo fix this mess, why do we have to pass "", NULL, "" here before cast restrictions?
{
tc = NULL;
}

View File

@@ -11,6 +11,7 @@
#include "utils.h"
#include "DeckManager.h"
#include <iomanip>
#include "AbilityParser.h"
#if defined (WIN32) || defined (LINUX)
#include <time.h>
@@ -341,6 +342,12 @@ int MTGAllCards::load(const char * config_file, const char * set_name, int autol
if (!s.size()) continue;
if (s[s.size() - 1] == '\r') s.erase(s.size() - 1); // Handle DOS files
if (!s.size()) continue;
if (s.find("#AUTO_DEFINE ") == 0)
{
AutoLineMacro::AddMacro(s.substr(13));
continue;
}
switch (conf_read_mode)
{
case MTGAllCards::READ_ANYTHING:

View File

@@ -26,7 +26,7 @@ const string Constants::kRetraceKeyword = "retrace";
const string Constants::kKickerKeyword = "kicker";
const string Constants::kMorphKeyword = "facedown";
int Constants::NB_Colors; //Store de Max number of colors
int Constants::NB_Colors = 0; //Store the Max number of colors.
const char* Constants::MTGBasicAbilities[] = {
"trample",

View File

@@ -828,6 +828,7 @@ int TargetChooser::countValidTargets()
int result = 0;
for (int i = 0; i < 2; ++i)
{
assert(observer);
Player *p = observer->players[i];
if(canTarget(p))
result++;

View File

@@ -302,6 +302,7 @@
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\AbilityParser.cpp" />
<ClCompile Include="src\ActionElement.cpp" />
<ClCompile Include="src\ActionLayer.cpp" />
<ClCompile Include="src\ActionStack.cpp" />
@@ -438,6 +439,7 @@
<None Include="Windows\Wagic.ico" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\AbilityParser.h" />
<ClInclude Include="include\ActionElement.h" />
<ClInclude Include="include\ActionLayer.h" />
<ClInclude Include="include\ActionStack.h" />

View File

@@ -319,6 +319,9 @@
<ClCompile Include="src\AIPlayerBakaB.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\AbilityParser.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\ActionElement.h">
@@ -663,6 +666,9 @@
<ClInclude Include="include\AIPlayerBakaB.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="include\AbilityParser.h">
<Filter>inc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Makefile" />

View File

@@ -45,6 +45,7 @@ PRECOMPILED_HEADER = include/PrecompiledHeader.h
# MGT
SOURCES += \
src/AbilityParser.cpp\
src/ActionElement.cpp\
src/ActionLayer.cpp\
src/ActionStack.cpp\

View File

@@ -41,6 +41,7 @@ PRECOMPILED_HEADER = include/PrecompiledHeader.h
# MGT
SOURCES += \
src/AbilityParser.cpp\
src/ActionElement.cpp\
src/ActionLayer.cpp\
src/ActionStack.cpp\