diff --git a/projects/mtg/Android/jni/Android.mk b/projects/mtg/Android/jni/Android.mk index 6fbc87b16..d09d4185d 100644 --- a/projects/mtg/Android/jni/Android.mk +++ b/projects/mtg/Android/jni/Android.mk @@ -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 \ diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 3630fee5b..58f9decaa 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -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) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 3e0716023..fcc46adce 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -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 diff --git a/projects/mtg/include/AbilityParser.h b/projects/mtg/include/AbilityParser.h new file mode 100644 index 000000000..44c31a389 --- /dev/null +++ b/projects/mtg/include/AbilityParser.h @@ -0,0 +1,26 @@ +#ifndef _ABILITY_PARSER_H_ +#define _ABILITY_PARSER_H_ + +#include +#include +using std::string; +using std::vector; +using std::map; + +class AutoLineMacro { +private: + string mName; + string mResult; + vector mParams; + void parse(string& s); + string process(string& s); + static vector gAutoLineMacros; + static map gAutoLineMacrosIndex; +public: + AutoLineMacro(string& s); + static void Destroy(); + static bool AddMacro(string& s); + static string Process(string& s); +}; + +#endif \ No newline at end of file diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 5ddfb6885..8dbbb28f7 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -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(); diff --git a/projects/mtg/src/AbilityParser.cpp b/projects/mtg/src/AbilityParser.cpp new file mode 100644 index 000000000..03a638e7b --- /dev/null +++ b/projects/mtg/src/AbilityParser.cpp @@ -0,0 +1,126 @@ +#include "PrecompiledHeader.h" + +#include "AbilityParser.h" +#include "utils.h" +#include + +using std::string; +using std::vector; + +vector AutoLineMacro::gAutoLineMacros; +map 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 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; +} \ No newline at end of file diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 376a18f1b..8255994fb 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -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; @@ -2486,9 +2486,9 @@ MultiAbility::~MultiAbility() } //Generic Target Ability -GenericTargetAbility::GenericTargetAbility(GameObserver* observer, string newName, string castRestriction,int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, +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); diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index b93dd9401..53ac8eb32 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -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=="); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 3c629dc0c..7d61e0237 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -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 * 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; } diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 0c90fa45b..690591a19 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -11,6 +11,7 @@ #include "utils.h" #include "DeckManager.h" #include +#include "AbilityParser.h" #if defined (WIN32) || defined (LINUX) #include @@ -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: diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index 3cc48f00f..6422722f5 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -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", diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 82e570bf7..51f17f835 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -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++; diff --git a/projects/mtg/template.vcxproj b/projects/mtg/template.vcxproj index aa94f9514..8d7052691 100644 --- a/projects/mtg/template.vcxproj +++ b/projects/mtg/template.vcxproj @@ -302,6 +302,7 @@ + @@ -438,6 +439,7 @@ + diff --git a/projects/mtg/template.vcxproj.filters b/projects/mtg/template.vcxproj.filters index bd429c388..1c1f12cb3 100644 --- a/projects/mtg/template.vcxproj.filters +++ b/projects/mtg/template.vcxproj.filters @@ -319,6 +319,9 @@ src + + src + @@ -663,6 +666,9 @@ inc + + inc + diff --git a/projects/mtg/wagic-SDL.pro b/projects/mtg/wagic-SDL.pro index 7d16fd073..7617aae78 100644 --- a/projects/mtg/wagic-SDL.pro +++ b/projects/mtg/wagic-SDL.pro @@ -45,6 +45,7 @@ PRECOMPILED_HEADER = include/PrecompiledHeader.h # MGT SOURCES += \ + src/AbilityParser.cpp\ src/ActionElement.cpp\ src/ActionLayer.cpp\ src/ActionStack.cpp\ diff --git a/projects/mtg/wagic-qt.pro b/projects/mtg/wagic-qt.pro index 3535c0c73..b29156d86 100644 --- a/projects/mtg/wagic-qt.pro +++ b/projects/mtg/wagic-qt.pro @@ -41,6 +41,7 @@ PRECOMPILED_HEADER = include/PrecompiledHeader.h # MGT SOURCES += \ + src/AbilityParser.cpp\ src/ActionElement.cpp\ src/ActionLayer.cpp\ src/ActionStack.cpp\