- Moved "game mode" types of awards outside of a code, and inside of a configuration file (rules/awards.dat). No code is required anymore to create such an award (momir, hermit basic, etc...)

- fixed compilation errors in GameObserver (windows)
This commit is contained in:
wagic.the.homebrew
2011-10-02 01:03:45 +00:00
parent 483c767492
commit 9e572ee416
15 changed files with 281 additions and 127 deletions

View File

@@ -0,0 +1,25 @@
[award]
name=Momir Mode
trophyroom_text=Won with exactly 8 lands.
id=prx_rimom
unlock_img=momir_unlocked.png
teaser=Interested in playing Momir Basic? You'll have to unlock it first :)
unlock_condition=type(land|myBattlefield)~equalto~8
[/award]
[award]
name=Hermit Druid Mode
id=prx_timreh
unlock_text=Hermit Druid Basic Unlocked
trophyroom_text=Won with less than 10 lands.
unlock_condition=type(land|myBattlefield)~lessthan~10
[/award]
[award]
name=Stone Hewer Mode
id=prx_rewehenots
unlock_text=Stone Hewer Basic Unlocked
teaser=Love Equipment and want a real challenge? Unlock Stone Hewer Basic:)
trophyroom_text=Won with more than 10 equipments.
unlock_condition=type(equipment|Battlefield)~morethan~10
[/award]

View File

@@ -13,6 +13,22 @@ class DeckStats;
using namespace std;
class Unlockable
{
private:
map <string, string>mValues;
public:
Unlockable();
void setValue(string, string);
string getValue(string);
bool isUnlocked();
bool tryToUnlock(GameObserver * game);
static void load();
static map <string, Unlockable *> unlockables;
static void Unlockable::Destroy();
};
class CreditBonus
{
public:
@@ -27,9 +43,6 @@ class Credits
private:
time_t gameLength;
int isDifficultyUnlocked(DeckStats * stats);
int isMomirUnlocked();
int isStoneHewerUnlocked();
int isHermitUnlocked();
int isEvilTwinUnlocked();
int isRandomDeckUnlocked();
int IsMoreAIDecksUnlocked(DeckStats * stats);

View File

@@ -81,9 +81,6 @@ public:
INTERRUPT_AFTEREND,
BEGIN_AWARDS, //Options after this use the GameOptionAward struct, which includes a timestamp.
DIFFICULTY_MODE_UNLOCKED = BEGIN_AWARDS,
MOMIR_MODE_UNLOCKED,
STONEHEWER_MODE_UNLOCKED,
HERMIT_MODE_UNLOCKED,
EVILTWIN_MODE_UNLOCKED,
RANDOMDECK_MODE_UNLOCKED,
AWARD_COLLECTOR,
@@ -361,6 +358,7 @@ public:
private:
vector<GameOption*> values;
map<string,GameOption*> unknownMap;
GameOption * factorNewGameOption(string optionName, string value = "");
};
class GameSettings

View File

@@ -61,6 +61,7 @@ public:
bool hidden;
string displayName;
int unlockOption;
string mUnlockOptionString;
static vector<Rules *> RulesList;
Rules(string bg = "");

View File

@@ -595,6 +595,7 @@ class WGuiAward: public WGuiItem
{
public:
WGuiAward(int _id, string name, string _text, string _details = "");
WGuiAward(string _id, string name, string _text, string _details = "");
virtual ~WGuiAward();
virtual void Render();
virtual bool Selectable()
@@ -614,6 +615,7 @@ public:
protected:
string details;
int id;
string textId;
string text;
};

View File

@@ -10,11 +10,129 @@
#include "GameStateShop.h"
#include "PlayerData.h"
map <string, Unlockable *> Unlockable::unlockables;
Unlockable::Unlockable()
{
}
void Unlockable::setValue(string k , string v)
{
mValues[k] = v;
}
string Unlockable::getValue(string k)
{
return mValues[k];
}
bool Unlockable::isUnlocked() {
string id = getValue("id");
assert(id.size() > 0);
return (options[id].number != 0);
}
bool Unlockable::tryToUnlock(GameObserver * game) {
if (isUnlocked())
return false;
string conditions = getValue("unlock_condition");
Player * p = game->players[0];
if (p->isAI())
return false;
// We need a card belonging to the player in order to call parceCastRestrictions
// The goal is usually to create objects such as targetChoosers, that are usually required
// for protection, or determining the card's owner
//Therefore here any card is ok
MTGCardInstance * dummyCard = p->game->battlefield->nb_cards
? p->game->battlefield->cards[0]
: p->game->hand->nb_cards
? p->game->hand->cards[0]
: p->game->library->nb_cards
? p->game->library->cards[0]
: NULL;
AbilityFactory af(game);
int meetConditions = conditions.size()
? dummyCard
? af.parseCastRestrictions(dummyCard, p, conditions)
: 0
: 1;
if (!meetConditions)
return false;
// Unlock the award and return
string id = getValue("id");
assert(id.size() > 0);
GameOptionAward* goa = (GameOptionAward*) &options[id];
goa->giveAward();
return true;
}
void Unlockable::load()
{
std::string contents;
if (! JFileSystem::GetInstance()->readIntoString("Rules/awards.dat", contents))
return;
std::stringstream stream(contents);
std::string s;
Unlockable * current = NULL;
while (std::getline(stream, s))
{
if (!s.size()) continue;
if (s[s.size() - 1] == '\r') s.erase(s.size() - 1); //Handle DOS files
if (!s.size()) continue;
if (s[0] == '#') continue;
if (s == "[award]")
{
current = NEW Unlockable();
continue;
}
if (!current)
continue;
if (s == "[/award]")
{
string id = current->getValue("id");
if (id.size())
unlockables[id] = current;
else
SAFE_DELETE(current);
continue;
}
vector<string> keyValue = split(s,'=');
if (keyValue.size() != 2)
continue;
current->setValue(keyValue[0], keyValue[1]);
}
}
void Unlockable::Destroy()
{
for (map<string, Unlockable *>::iterator it = unlockables.begin(); it != unlockables.end(); ++it) {
SAFE_DELETE(it->second);
}
unlockables.clear();
}
CreditBonus::CreditBonus(int _value, string _text)
{
value = _value;
text = _text;
}
void CreditBonus::Render(float x, float y, WFont * font)
@@ -129,59 +247,48 @@ void Credits::compute(GameObserver* g, GameApp * _app)
unlockedTextureName = "unlocked.png";
goa = (GameOptionAward*) &options[Options::DIFFICULTY_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isMomirUnlocked()))
else
{
unlockedTextureName = "momir_unlocked.png";
goa = (GameOptionAward*) &options[Options::MOMIR_MODE_UNLOCKED];
goa->giveAward();
options.save();
for (map<string, Unlockable *>::iterator it = Unlockable::unlockables.begin(); it != Unlockable::unlockables.end(); ++it) {
Unlockable * award = it->second;
if (award->tryToUnlock(g))
{
unlocked = 1;
unlockedString = award->getValue("unlock_text");
unlockedTextureName = award->getValue("unlock_img");
break;
}
}
}
else if ((unlocked = isStoneHewerUnlocked()))
{
//unlockedTextureName = "stonehewer_unlocked.png";//until we can find a nice free use font.
CreditBonus * b = NEW CreditBonus(0, _("Stone Hewer Basic Unlocked"));
bonus.push_back(b);
goa = (GameOptionAward*) &options[Options::STONEHEWER_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isHermitUnlocked()))
{
//unlockedTextureName = "hermit_unlocked.png";//until we can find a nice free use font.
CreditBonus * b = NEW CreditBonus(0, _("Hermit Druid Basic Unlocked"));
bonus.push_back(b);
goa = (GameOptionAward*) &options[Options::HERMIT_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isEvilTwinUnlocked()))
if (!unlocked)
{
unlockedTextureName = "eviltwin_unlocked.png";
goa = (GameOptionAward*) &options[Options::EVILTWIN_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isRandomDeckUnlocked()))
{
unlockedTextureName = "randomdeck_unlocked.png";
goa = (GameOptionAward*) &options[Options::RANDOMDECK_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = unlockRandomSet()))
{
unlockedTextureName = "set_unlocked.png";
MTGSetInfo * si = setlist.getInfo(unlocked - 1);
if (si)
unlockedString = si->getName(); //Show the set's pretty name for unlocks.
}
else if ((unlocked = IsMoreAIDecksUnlocked(stats)))
{
options[Options::AIDECKS_UNLOCKED].number += 10;
options.save();
unlockedTextureName = "ai_unlocked.png";
if ((unlocked = isEvilTwinUnlocked()))
{
unlockedTextureName = "eviltwin_unlocked.png";
goa = (GameOptionAward*) &options[Options::EVILTWIN_MODE_UNLOCKED];
goa->giveAward();
}
else if ((unlocked = isRandomDeckUnlocked()))
{
unlockedTextureName = "randomdeck_unlocked.png";
goa = (GameOptionAward*) &options[Options::RANDOMDECK_MODE_UNLOCKED];
goa->giveAward();
}
else if ((unlocked = unlockRandomSet()))
{
unlockedTextureName = "set_unlocked.png";
MTGSetInfo * si = setlist.getInfo(unlocked - 1);
if (si)
unlockedString = si->getName(); //Show the set's pretty name for unlocks.
}
else if ((unlocked = IsMoreAIDecksUnlocked(stats)))
{
options[Options::AIDECKS_UNLOCKED].number += 10;
options.save();
unlockedTextureName = "ai_unlocked.png";
}
}
if (unlocked && options[Options::SFXVOLUME].number > 0)
@@ -232,11 +339,11 @@ JQuadPtr Credits::GetUnlockedQuad(string textureName)
if (!unlockedTex) return JQuadPtr();
return WResourceManager::Instance()->RetrieveQuad(
unlockedTextureName,
2.0f,
2.0f,
static_cast<float>(unlockedTex->mWidth - 4),
static_cast<float>(unlockedTex->mHeight - 4));
unlockedTextureName,
2.0f,
2.0f,
static_cast<float>(unlockedTex->mWidth - 4),
static_cast<float>(unlockedTex->mHeight - 4));
}
@@ -255,6 +362,7 @@ void Credits::Render()
f3->SetScale(1);
f3->SetColor(ARGB(255,255,255,255));
char buffer[512];
if (!observer->turn)
{
sprintf(buffer, "%s", _("Please check your deck (not enough cards?)").c_str());
@@ -308,7 +416,7 @@ void Credits::Render()
y += 15;
//!!
if (observer->gameOver != p1)
if (observer->gameOver != p1 && this->gameLength != 0)
{
sprintf(buffer, _("Game length: %i turns (%i seconds)").c_str(), observer->turn, this->gameLength);
f->DrawString(buffer, 10, y);
@@ -357,33 +465,6 @@ int Credits::isDifficultyUnlocked(DeckStats * stats)
return 0;
}
int Credits::isMomirUnlocked()
{
if (options[Options::MOMIR_MODE_UNLOCKED].number)
return 0;
if (p1->game->inPlay->countByType("land") == 8)
return 1;
return 0;
}
int Credits::isStoneHewerUnlocked()
{
if (options[Options::STONEHEWER_MODE_UNLOCKED].number)
return 0;
if (int(p1->game->inPlay->countByType("equipment") + p1->opponent()->game->inPlay->countByType("equipment")) > 10)
return 1;
return 0;
}
int Credits::isHermitUnlocked()
{
if (options[Options::HERMIT_MODE_UNLOCKED].number)
return 0;
if (int(p1->game->inPlay->countByType("land")) < 10)
return 1;
return 0;
}
int Credits::isEvilTwinUnlocked()
{
if (options[Options::EVILTWIN_MODE_UNLOCKED].number)

View File

@@ -29,6 +29,7 @@
#include "Rules.h"
#include "ModRules.h"
#include "JFileSystem.h"
#include "Credits.h"
#define DEFAULT_DURATION .25
@@ -138,6 +139,9 @@ void GameApp::Create()
//Load Mod Rules before everything else
gModRules.load("rules/modrules.xml");
//Load awards (needs to be loaded before any option are accessed)
Unlockable::load();
//Link this to our settings manager.
options.theGame = this;
@@ -316,6 +320,7 @@ void GameApp::Destroy()
DeckEditorMenu::destroy();
options.theGame = NULL;
Unlockable::Destroy();
Rules::unloadAllRules();
LOG("==Destroying GameApp Successful==");

View File

@@ -335,7 +335,7 @@ GameObserver::~GameObserver()
SAFE_DELETE(mLayers);
SAFE_DELETE(phaseRing);
SAFE_DELETE(replacementEffects);
for (int i = 0; i < players.size(); ++i)
for (size_t i = 0; i < players.size(); ++i)
{
SAFE_DELETE(players[i]);
}
@@ -784,7 +784,7 @@ void GameObserver::Render()
if (mExtraPayment)
mExtraPayment->Render();
for (int i = 0; i < players.size(); ++i)
for (size_t i = 0; i < players.size(); ++i)
{
players[i]->Render();
}

View File

@@ -5,6 +5,7 @@
#include "Translate.h"
#include "OptionItem.h"
#include "StyleManager.h"
#include "Credits.h"
const string Options::optionNames[] = {
//Global options
@@ -65,9 +66,6 @@ const string Options::optionNames[] = {
"interruptAfterEnd",
//Unlocked modes
"prx_handler",
"prx_rimom",
"prx_rewehenots",
"prx_timreh",
"prx_eviltwin",
"prx_rnddeck",
"aw_collector",
@@ -335,7 +333,7 @@ int GameOptions::load()
int id = Options::getID(name);
if (id == INVALID_OPTION)
{
if (!unknownMap[name]) unknownMap[name] = NEW GameOption(val);
if (!unknownMap[name]) unknownMap[name] = factorNewGameOption(name, val);
continue;
}
@@ -420,12 +418,31 @@ GameOption& GameOptions::operator[](string optionName)
}
GameOption * GameOptions::factorNewGameOption(string optionName, string value)
{
if (optionName == "prx_rimom")
int a = 0;
GameOption * result =( Unlockable::unlockables.find(optionName) != Unlockable::unlockables.end())
? NEW GameOptionAward()
: NEW GameOption();
if (value.size())
result->read(value);
return result;
}
GameOption * GameOptions::get(string optionName)
{
if (!unknownMap[optionName])
unknownMap[optionName] = NEW GameOption(0);
if (optionName == "prx_rimom")
int a = 0;
return unknownMap[optionName];
if (!unknownMap[optionName])
{
unknownMap[optionName] = factorNewGameOption(optionName);
}
return unknownMap[optionName];
}
GameOption * GameOptions::get(int optionID)
@@ -619,10 +636,6 @@ GameOption& GameSettings::operator[](string optionName)
GameOption* GameSettings::get(int optionID)
{
#ifdef DEBUG
string option_name = Options::getName(optionID);
#endif
if (optionID < 0)
return &invalid_option;
else if (globalOptions && optionID <= Options::LAST_GLOBAL)

View File

@@ -10,6 +10,7 @@
#include "Translate.h"
#include "OptionItem.h"
#include "DeckDataWrapper.h"
#include "Credits.h"
enum ENUM_AWARDS_STATE
{
@@ -71,17 +72,12 @@ void GameStateAwards::Start()
btn = NEW WGuiButton(aw, GUI_AWARD_BUTTON, Options::DIFFICULTY_MODE_UNLOCKED, this);
listview->Add(btn);
aw = NEW WGuiAward(Options::MOMIR_MODE_UNLOCKED, "Momir Mode", "Won with exactly 8 lands.");
btn = NEW WGuiButton(aw, GUI_AWARD_BUTTON, Options::MOMIR_MODE_UNLOCKED, this);
listview->Add(btn);
aw = NEW WGuiAward(Options::STONEHEWER_MODE_UNLOCKED, "Stone Hewer Mode", "Won with more than 10 equipments.");
btn = NEW WGuiButton(aw, GUI_AWARD_BUTTON, Options::STONEHEWER_MODE_UNLOCKED, this);
listview->Add(btn);
aw = NEW WGuiAward(Options::HERMIT_MODE_UNLOCKED, "Hermit Druid Mode", "Won with less than 10 lands.");
btn = NEW WGuiButton(aw, GUI_AWARD_BUTTON, Options::HERMIT_MODE_UNLOCKED, this);
listview->Add(btn);
for (map<string, Unlockable *>::iterator it = Unlockable::unlockables.begin(); it != Unlockable::unlockables.end(); ++it) {
Unlockable * award = it->second;
aw = NEW WGuiAward(award->getValue("id"), award->getValue("name"), award->getValue("trophyroom_text"));
btn = NEW WGuiButton(aw, GUI_AWARD_BUTTON, 0, this);
listview->Add(btn);
}
aw = NEW WGuiAward(Options::EVILTWIN_MODE_UNLOCKED, "Evil Twin Mode", "Won with same army size.");
btn = NEW WGuiButton(aw, GUI_AWARD_BUTTON, Options::EVILTWIN_MODE_UNLOCKED, this);

View File

@@ -485,6 +485,7 @@ void GameStateDuel::Update(float dt)
//run a "post update" init call in the rules. This is for things such as Manapool, which gets emptied in the update
// That's mostly because of a legacy bug, where we use the update sequence for some things when we should use events (such as phase changes)
mParent->rules->postUpdateInit(game);
if (game->gameOver)
{
if (game->players[1]->playMode != Player::MODE_TEST_SUITE) credits->compute(game, mParent);

View File

@@ -20,6 +20,7 @@
#include <JLogger.h>
#include "Rules.h"
#include "ModRules.h"
#include "Credits.h"
#ifdef NETWORK_SUPPORT
#include <JNetwork.h>
@@ -214,14 +215,16 @@ void GameStateMenu::fillScroller()
if (!options[Options::DIFFICULTY_MODE_UNLOCKED].number)
scroller->Add(_("Unlock the difficult mode for more challenging duels!"));
if (!options[Options::MOMIR_MODE_UNLOCKED].number)
scroller->Add(_("Interested in playing Momir Basic? You'll have to unlock it first :)"));
if (!options[Options::STONEHEWER_MODE_UNLOCKED].number)
scroller->Add(_("Love Equipment and want a real challenge? Unlock Stone Hewer Basic:)"));
if (!options[Options::RANDOMDECK_MODE_UNLOCKED].number)
scroller->Add(_("You haven't unlocked the random deck mode yet"));
if (!options[Options::EVILTWIN_MODE_UNLOCKED].number)
scroller->Add(_("You haven't unlocked the evil twin mode yet"));
for (map<string, Unlockable *>::iterator it = Unlockable::unlockables.begin(); it != Unlockable::unlockables.end(); ++it) {
Unlockable * award = it->second;
if (!award->isUnlocked())
{
if (award->getValue("teaser").size())
scroller->Add(_(award->getValue("teaser")));
}
}
if (!options[Options::RANDOMDECK_MODE_UNLOCKED].number)
scroller->Add(_("You haven't unlocked the random deck mode yet"));
if (!options[Options::EVILTWIN_MODE_UNLOCKED].number)
@@ -620,7 +623,10 @@ void GameStateMenu::Update(float dt)
for (size_t i = 0; i < Rules::RulesList.size(); ++i)
{
Rules * rules = Rules::RulesList[i];
if (!rules->hidden && (rules->unlockOption == INVALID_OPTION || options[rules->unlockOption].number))
bool unlocked = rules->unlockOption == INVALID_OPTION
? (rules->mUnlockOptionString.size() == 0 || options[rules->mUnlockOptionString].number !=0)
: options[rules->unlockOption].number != 0;
if (!rules->hidden && (unlocked))
{
subMenuController->Add(SUBMENUITEM_END_OFFSET + i, rules->displayName.c_str());
}

View File

@@ -71,7 +71,7 @@ int MTGAbility::allowedToAltCast(MTGCardInstance * card,Player * player)
return af.parseCastRestrictions(card,player,card->getOtherRestrictions());
}
int AbilityFactory::parseCastRestrictions(MTGCardInstance * card,Player * player,string restrictions)
int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * player,string restrictions)
{
vector <string> restriction = split(restrictions, ',');
AbilityFactory af(observer);
@@ -3954,6 +3954,7 @@ int Trigger::triggerOnEvent(WEvent * event) {
return 1;//can't check these restrictions without a source aka:in a rule.txt
AbilityFactory af(game);
int checkCond = af.parseCastRestrictions(source,source->controller(),castRestriction);
if(!checkCond)
return 0;
}

View File

@@ -546,7 +546,8 @@ int Rules::load(string _filename)
}
else if (s.find("unlock=") == 0)
{
unlockOption = Options::getID(s.substr(7));
mUnlockOptionString = s.substr(7);
unlockOption = Options::getID(mUnlockOptionString);
}
else if (s.find("hidden") == 0)
{

View File

@@ -1293,7 +1293,7 @@ void WGuiAward::Underlay()
char buf[1024];
JQuadPtr trophy;
string n = Options::getName(id);
string n = id ? Options::getName(id) : textId;
if (n.size())
{
sprintf(buf, "trophy_%s.png", n.c_str()); //Trophy specific to the award
@@ -1316,7 +1316,7 @@ void WGuiAward::Underlay()
}
void WGuiAward::Render()
{
GameOptionAward * goa = dynamic_cast<GameOptionAward*> (&options[id]);
GameOptionAward * goa = id ? dynamic_cast<GameOptionAward*> (&options[id]) : dynamic_cast<GameOptionAward*> (&options[textId]);
if (!goa) return;
@@ -1359,6 +1359,17 @@ WGuiAward::WGuiAward(int _id, string name, string _text, string _details) :
height = 60;
details = _details;
}
WGuiAward::WGuiAward(string _id, string name, string _text, string _details) :
WGuiItem(name)
{
id = 0;
textId = _id;
text = _text;
height = 60;
details = _details;
}
WGuiAward::~WGuiAward()
{
GameOptionAward * goa = dynamic_cast<GameOptionAward*> (&options[id]);
@@ -1367,7 +1378,7 @@ WGuiAward::~WGuiAward()
bool WGuiAward::Visible()
{
//WGuiAward is only visible when it's tied to an already achieved award.
GameOptionAward * goa = dynamic_cast<GameOptionAward*> (&options[id]);
GameOptionAward * goa = id ? dynamic_cast<GameOptionAward*> (&options[id]) : dynamic_cast<GameOptionAward*> (&options[textId]);
if (!goa || !goa->number) return false;
return true;
}