Erwan
- Reward system in Story mode (currently, either credits or random set) - Rules now accept for player 2 to start (see story mode "block" stage) - Story mode now has an autosave/autoload mechanism. This is for convenience but also to prevent people from abusing the reward mechanism too easily. - possibility to choose an avatar for both players through the rules (see example in story mode)
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
[INIT]
|
||||||
|
mode=mtg
|
||||||
|
player=2
|
||||||
|
phase=combat_attackers
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:grizzly bears
|
||||||
|
life:1
|
||||||
|
auto=@movedTo(*|graveyard): winGame controller
|
||||||
|
[PLAYER2]
|
||||||
|
inplay:raging goblin
|
||||||
|
auto=lord(goblin) mustattack
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
<text>in my life, enough to understand the basics of their craft...</text>
|
<text>in my life, enough to understand the basics of their craft...</text>
|
||||||
|
|
||||||
<answer goto="tap_mana_intro" align="center" x="0.30" font="1">I want to know more</answer>
|
<answer goto="tap_mana_intro" align="center" x="0.30" font="1">I want to know more</answer>
|
||||||
<answer goto="tap_mana_intro" x="0.80" y="-1">Take me back to the menu</answer>
|
<answer goto="End" x="0.80" y="-1">Take me back to the menu</answer>
|
||||||
|
<answer goto="block">Continue</answer>
|
||||||
</page>
|
</page>
|
||||||
|
|
||||||
<page id="tap_mana_intro">
|
<page id="tap_mana_intro">
|
||||||
@@ -138,13 +139,48 @@
|
|||||||
<text>- Block your opponent's attacking creatures during the "blockers" phase of his turn.</text>
|
<text>- Block your opponent's attacking creatures during the "blockers" phase of his turn.</text>
|
||||||
<text>There are lots of other phases but we'll discuss them later</text>
|
<text>There are lots of other phases but we'll discuss them later</text>
|
||||||
|
|
||||||
|
<answer goto="block_1">Continue</answer>
|
||||||
|
</page>
|
||||||
|
|
||||||
|
<page id="block_1">
|
||||||
|
<type>dialog</type>
|
||||||
|
<title>blocking</title>
|
||||||
|
<text>Now let's block!</text>
|
||||||
|
<text>Your opponent will attack you with one of its creatures.</text>
|
||||||
|
<text>When comes the "blockers" phase, I want you to click on your own creature</text>
|
||||||
|
<text>to block his attack</text>
|
||||||
|
<text>If you don't, his creature will kill you</text>
|
||||||
|
|
||||||
|
<answer goto="block">Continue</answer>
|
||||||
|
</page>
|
||||||
|
|
||||||
|
<page id="block">
|
||||||
|
<type>duel</type>
|
||||||
|
<onwin>block_ok</onwin>
|
||||||
|
<onlose>block_try_again</onlose>
|
||||||
|
</page>
|
||||||
|
|
||||||
|
<page id="block_try_again">
|
||||||
|
<type>dialog</type>
|
||||||
|
<title>Oh well</title>
|
||||||
|
<text>Your opponent killed you</text>
|
||||||
|
<text>Be sure to click once on your grizzly bears when the opponent attacks you</text>
|
||||||
|
<answer goto="block">Let's try again!</answer>
|
||||||
|
</page>
|
||||||
|
|
||||||
|
<page id="block_ok">
|
||||||
|
<type>dialog</type>
|
||||||
|
<title>Great!</title>
|
||||||
|
<text>You now understand the basics of the combat phase</text>
|
||||||
<answer goto="End">Continue</answer>
|
<answer goto="End">Continue</answer>
|
||||||
</page>
|
</page>
|
||||||
|
|
||||||
<page id="End">
|
<page id="End">
|
||||||
<type>End</type>
|
<type>End</type>
|
||||||
<title>CONGRATULATIONS!</title>
|
<title>CONGRATULATIONS!</title>
|
||||||
<text>This is the end of this tutorial,</text>
|
<text>This is the end of this tutorial.</text>
|
||||||
<text>now time for you to fight some real ennemies!</text>
|
<reward type="credits" value="1000">Here's a 1000 credits coupon to get you started, come and visit my shop!</reward>
|
||||||
|
<reward type="unlockset" >And I'm nice, I unlocked ${SET} for you!</reward>
|
||||||
|
<text>Now time for you to fight some real ennemies!</text>
|
||||||
<text>Click on the action button to go back to the main menu</text>
|
<text>Click on the action button to go back to the main menu</text>
|
||||||
</page>
|
</page>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[INIT]
|
[INIT]
|
||||||
mode=mtg
|
mode=mtg
|
||||||
[PLAYER1]
|
[PLAYER1]
|
||||||
|
avatar:campaigns/01.Where it all begins/_gfx/willow.jpg
|
||||||
inplay:forest
|
inplay:forest
|
||||||
auto=@tapped(land|myinplay):wingame controller
|
auto=@tapped(land|myinplay):wingame controller
|
||||||
auto=@next combatbegins:wingame opponent
|
auto=@next combatbegins:wingame opponent
|
||||||
@@ -29,7 +29,6 @@ private:
|
|||||||
int isMomirUnlocked();
|
int isMomirUnlocked();
|
||||||
int isEvilTwinUnlocked();
|
int isEvilTwinUnlocked();
|
||||||
int isRandomDeckUnlocked();
|
int isRandomDeckUnlocked();
|
||||||
int unlockRandomSet();
|
|
||||||
public:
|
public:
|
||||||
int value;
|
int value;
|
||||||
Player * p1, *p2;
|
Player * p1, *p2;
|
||||||
@@ -44,6 +43,8 @@ public:
|
|||||||
~Credits();
|
~Credits();
|
||||||
void compute(Player * _p1, Player * _p2, GameApp * _app);
|
void compute(Player * _p1, Player * _p2, GameApp * _app);
|
||||||
void Render();
|
void Render();
|
||||||
|
static int unlockRandomSet(bool force = false);
|
||||||
|
static int addCreditBonus(int value);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ class GameObserver{
|
|||||||
queue<WEvent *> eventsQueue;
|
queue<WEvent *> eventsQueue;
|
||||||
|
|
||||||
int nbPlayers;
|
int nbPlayers;
|
||||||
int currentPlayerId;
|
|
||||||
int untap(MTGCardInstance * card);
|
int untap(MTGCardInstance * card);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int currentPlayerId;
|
||||||
CombatStep combatStep;
|
CombatStep combatStep;
|
||||||
int turn;
|
int turn;
|
||||||
int forceShuffleLibraries();
|
int forceShuffleLibraries();
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ private:
|
|||||||
list<Phase *> ring;
|
list<Phase *> ring;
|
||||||
list<Phase *>::iterator current;
|
list<Phase *>::iterator current;
|
||||||
Phase * getCurrentPhase();
|
Phase * getCurrentPhase();
|
||||||
Phase * forward();
|
Phase * forward(bool sendEvents = true);
|
||||||
Phase * goToPhase(int id, Player * player);
|
Phase * goToPhase(int id, Player * player,bool sendEvents = true);
|
||||||
PhaseRing(Player* players[], int nbPlayers=2);
|
PhaseRing(Player* players[], int nbPlayers=2);
|
||||||
~PhaseRing();
|
~PhaseRing();
|
||||||
int addPhase(Phase * phase);
|
int addPhase(Phase * phase);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ class Player: public Damageable{
|
|||||||
|
|
||||||
virtual int receiveEvent(WEvent * event){return 0;};
|
virtual int receiveEvent(WEvent * event){return 0;};
|
||||||
virtual void Render(){};
|
virtual void Render(){};
|
||||||
|
void loadAvatar(string file);
|
||||||
};
|
};
|
||||||
|
|
||||||
class HumanPlayer: public Player{
|
class HumanPlayer: public Player{
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
class PlayerData{
|
class PlayerData{
|
||||||
protected:
|
protected:
|
||||||
|
void init();
|
||||||
public:
|
public:
|
||||||
int credits;
|
int credits;
|
||||||
|
map<string,string>storySaves;
|
||||||
MTGDeck * collection;
|
MTGDeck * collection;
|
||||||
TaskList * taskList;
|
TaskList * taskList;
|
||||||
|
PlayerData(); //This doesn't init the collection, do not use it to manipulate the player's collection
|
||||||
PlayerData(MTGAllCards * allcards);
|
PlayerData(MTGAllCards * allcards);
|
||||||
~PlayerData();
|
~PlayerData();
|
||||||
int save();
|
int save();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class RulesPlayerData{
|
|||||||
public:
|
public:
|
||||||
vector <string> extraRules;
|
vector <string> extraRules;
|
||||||
int life;
|
int life;
|
||||||
|
string avatar;
|
||||||
ManaCost * manapool;
|
ManaCost * manapool;
|
||||||
RulesPlayerZone zones[5];
|
RulesPlayerZone zones[5];
|
||||||
RulesPlayerData();
|
RulesPlayerData();
|
||||||
@@ -36,6 +37,7 @@ class RulesPlayerData{
|
|||||||
class RulesState{
|
class RulesState{
|
||||||
public:
|
public:
|
||||||
int phase;
|
int phase;
|
||||||
|
int player;
|
||||||
void parsePlayerState(int playerId, string s);
|
void parsePlayerState(int playerId, string s);
|
||||||
RulesState();
|
RulesState();
|
||||||
RulesPlayerData playerData[2];
|
RulesPlayerData playerData[2];
|
||||||
|
|||||||
@@ -45,6 +45,25 @@ StoryImage(string img, float mX, float mY);
|
|||||||
float getHeight();
|
float getHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StoryReward:public StoryText {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
STORY_REWARD_CREDITS,
|
||||||
|
STORY_REWARD_SET
|
||||||
|
};
|
||||||
|
|
||||||
|
int rewardDone;
|
||||||
|
string value;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
StoryReward(string _type, string _value, string text, float _mX, float _mY, string align = "center", int font = 0, int id = 0);
|
||||||
|
void Update(float dt);
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
static bool rewardSoundPlayed;
|
||||||
|
static bool rewardsEnabled;
|
||||||
|
};
|
||||||
|
|
||||||
class StoryChoice:public StoryText {
|
class StoryChoice:public StoryText {
|
||||||
public:
|
public:
|
||||||
string pageId;
|
string pageId;
|
||||||
@@ -110,6 +129,7 @@ private:
|
|||||||
map<string,StoryPage *>pages;
|
map<string,StoryPage *>pages;
|
||||||
bool parse(string filename);
|
bool parse(string filename);
|
||||||
StoryPage * loadPage(TiXmlElement* element);
|
StoryPage * loadPage(TiXmlElement* element);
|
||||||
|
bool _gotoPage(string id);
|
||||||
public:
|
public:
|
||||||
string currentPageId;
|
string currentPageId;
|
||||||
string folder;
|
string folder;
|
||||||
@@ -117,6 +137,7 @@ public:
|
|||||||
~StoryFlow();
|
~StoryFlow();
|
||||||
|
|
||||||
bool gotoPage(string id);
|
bool gotoPage(string id);
|
||||||
|
bool loadPageId(string id);
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
void Render();
|
void Render();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){
|
|||||||
p1 = _p1;
|
p1 = _p1;
|
||||||
p2 = _p2;
|
p2 = _p2;
|
||||||
app = _app;
|
app = _app;
|
||||||
showMsg = (WRand() % 5);
|
showMsg = (WRand() % 3);
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
if (!g->turn) return;
|
if (!g->turn) return;
|
||||||
PlayerData * playerdata = NEW PlayerData(app->collection);
|
PlayerData * playerdata = NEW PlayerData(app->collection);
|
||||||
@@ -126,18 +126,17 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){
|
|||||||
}else if((unlocked = unlockRandomSet())) {
|
}else if((unlocked = unlockRandomSet())) {
|
||||||
unlockedTex = resources.RetrieveTexture("set_unlocked.png");
|
unlockedTex = resources.RetrieveTexture("set_unlocked.png");
|
||||||
unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96);
|
unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96);
|
||||||
goa = (GameOptionAward*) &options[Options::optionSet(unlocked - 1)];
|
|
||||||
goa->giveAward();
|
|
||||||
options.save();
|
|
||||||
MTGSetInfo * si = setlist.getInfo(unlocked - 1);
|
MTGSetInfo * si = setlist.getInfo(unlocked - 1);
|
||||||
if(si) unlockedString = si->getName(); //Show the set's pretty name for unlocks.
|
if(si) unlockedString = si->getName(); //Show the set's pretty name for unlocks.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlocked && options[Options::SFXVOLUME].number > 0){
|
if (unlocked && options[Options::SFXVOLUME].number > 0){
|
||||||
JSample * sample = resources.RetrieveSample("bonus.wav");
|
JSample * sample = resources.RetrieveSample("bonus.wav");
|
||||||
if (sample){
|
if (sample){
|
||||||
JSoundSystem::GetInstance()->PlaySample(sample);
|
JSoundSystem::GetInstance()->PlaySample(sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<CreditBonus *>::iterator it;
|
vector<CreditBonus *>::iterator it;
|
||||||
@@ -283,11 +282,36 @@ int Credits::isRandomDeckUnlocked(){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Credits::unlockRandomSet(){
|
int Credits::addCreditBonus(int value){
|
||||||
|
PlayerData * playerdata = NEW PlayerData();
|
||||||
|
playerdata->credits += value;
|
||||||
|
playerdata->save();
|
||||||
|
SAFE_DELETE(playerdata);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Credits::unlockRandomSet(bool force){
|
||||||
int setId = WRand() % setlist.size();
|
int setId = WRand() % setlist.size();
|
||||||
|
|
||||||
|
if (force) {
|
||||||
|
int init = setId;
|
||||||
|
boolean found = false;
|
||||||
|
do {
|
||||||
|
if (1 != options[Options::optionSet(setId)].number)
|
||||||
|
found = true;
|
||||||
|
else {
|
||||||
|
setId++;
|
||||||
|
if (setId == setlist.size())
|
||||||
|
setId = 0;
|
||||||
|
}
|
||||||
|
} while (setId != init && !found);
|
||||||
|
}
|
||||||
|
|
||||||
if (1 == options[Options::optionSet(setId)].number)
|
if (1 == options[Options::optionSet(setId)].number)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
GameOptionAward* goa = (GameOptionAward*) &options[Options::optionSet(setId)];
|
||||||
|
goa->giveAward();
|
||||||
|
options.save();
|
||||||
return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
|
return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,12 +193,14 @@ void GameObserver::startGame(Rules * rules){
|
|||||||
mLayers = NEW DuelLayers();
|
mLayers = NEW DuelLayers();
|
||||||
mLayers->init();
|
mLayers->init();
|
||||||
|
|
||||||
|
currentPlayerId = 0;
|
||||||
currentPlayer = players[0];
|
currentPlayer = players[0];
|
||||||
currentActionPlayer = currentPlayer;
|
currentActionPlayer = currentPlayer;
|
||||||
phaseRing = NEW PhaseRing(players,nbPlayers);
|
phaseRing = NEW PhaseRing(players,nbPlayers);
|
||||||
if (rules)
|
if (rules)
|
||||||
rules->initGame();
|
rules->initGame();
|
||||||
|
|
||||||
|
|
||||||
//Preload images from hand
|
//Preload images from hand
|
||||||
if (!players[0]->isAI()){
|
if (!players[0]->isAI()){
|
||||||
for (int i=0; i< players[0]->game->hand->nb_cards; i++){
|
for (int i=0; i< players[0]->game->hand->nb_cards; i++){
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
static const char* GAME_VERSION = "WTH?! 0.11.1 - by wololo";
|
static const char* GAME_VERSION = "WTH?! 0.11.1 - by wololo";
|
||||||
|
|
||||||
#define DEFAULT_ANGLE_MULTIPLIER 0.4
|
#define DEFAULT_ANGLE_MULTIPLIER 0.4f
|
||||||
#define MAX_ANGLE_MULTIPLIER (3*M_PI)
|
#define MAX_ANGLE_MULTIPLIER (3*M_PI)
|
||||||
#define MIN_ANGLE_MULTIPLIER 0.4
|
#define MIN_ANGLE_MULTIPLIER 0.4f
|
||||||
static const double STEP_ANGLE_MULTIPLIER = 0.0002;
|
static const double STEP_ANGLE_MULTIPLIER = 0.0002;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -76,9 +76,7 @@ void GameStateStory::Update(float dt) {
|
|||||||
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU);
|
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
flow->Update(dt);
|
||||||
flow->Update(dt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,30 +73,32 @@ Phase * PhaseRing::getCurrentPhase(){
|
|||||||
return *current;
|
return *current;
|
||||||
}
|
}
|
||||||
|
|
||||||
Phase * PhaseRing::forward(){
|
Phase * PhaseRing::forward(bool sendEvents){
|
||||||
Phase * cPhaseOld = *current;
|
Phase * cPhaseOld = *current;
|
||||||
if (current != ring.end()) current++;
|
if (current != ring.end()) current++;
|
||||||
if (current == ring.end()) current = ring.begin();
|
if (current == ring.end()) current = ring.begin();
|
||||||
|
|
||||||
//Warn the layers about the phase Change
|
if (sendEvents) {
|
||||||
WEvent * e = NEW WEventPhaseChange(cPhaseOld, *current);
|
//Warn the layers about the phase Change
|
||||||
GameObserver::GetInstance()->receiveEvent(e);
|
WEvent * e = NEW WEventPhaseChange(cPhaseOld, *current);
|
||||||
//delete e;
|
GameObserver::GetInstance()->receiveEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
return *current;
|
return *current;
|
||||||
}
|
}
|
||||||
|
|
||||||
Phase * PhaseRing::goToPhase(int id, Player * player){
|
Phase * PhaseRing::goToPhase(int id, Player * player, bool sendEvents){
|
||||||
Phase * currentPhase = *current;
|
Phase * currentPhase = *current;
|
||||||
while(currentPhase->id !=id || currentPhase->player != player){ //Dangerous, risk for inifinte loop !
|
while(currentPhase->id !=id || currentPhase->player != player){ //Dangerous, risk for inifinte loop !
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
OutputDebugString("goto");
|
OutputDebugString("goto");
|
||||||
#endif
|
#endif
|
||||||
currentPhase = forward();
|
currentPhase = forward(sendEvents);
|
||||||
}
|
}
|
||||||
return currentPhase;
|
return currentPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PhaseRing::addPhase(Phase * phase){
|
int PhaseRing::addPhase(Phase * phase){
|
||||||
ring.push_back(phase);
|
ring.push_back(phase);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -29,6 +29,19 @@ Player::~Player(){
|
|||||||
mAvatarTex = NULL;
|
mAvatarTex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::loadAvatar(string file){
|
||||||
|
if (mAvatarTex) {
|
||||||
|
resources.Release(mAvatarTex);
|
||||||
|
mAvatar = NULL;
|
||||||
|
mAvatarTex = NULL;
|
||||||
|
}
|
||||||
|
mAvatarTex = resources.RetrieveTexture(file,RETRIEVE_LOCK,TEXTURE_SUB_AVATAR);
|
||||||
|
if (mAvatarTex)
|
||||||
|
mAvatar = resources.RetrieveQuad(file,0,0,35,50,"playerAvatar",RETRIEVE_NORMAL,TEXTURE_SUB_AVATAR);
|
||||||
|
else
|
||||||
|
mAvatar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const string Player::getDisplayName() const {
|
const string Player::getDisplayName() const {
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
if (this == g->players[0]) return "Player 1";
|
if (this == g->players[0]) return "Player 1";
|
||||||
@@ -58,11 +71,7 @@ Player * Player::opponent(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
HumanPlayer::HumanPlayer(MTGPlayerCards * deck, string file, string fileSmall) : Player(deck, file, fileSmall) {
|
HumanPlayer::HumanPlayer(MTGPlayerCards * deck, string file, string fileSmall) : Player(deck, file, fileSmall) {
|
||||||
mAvatarTex = resources.RetrieveTexture("avatar.jpg",RETRIEVE_LOCK,TEXTURE_SUB_AVATAR);
|
loadAvatar("avatar.jpg");
|
||||||
if (mAvatarTex)
|
|
||||||
mAvatar = resources.RetrieveQuad("avatar.jpg",0,0,35,50,"playerAvatar",RETRIEVE_NORMAL,TEXTURE_SUB_AVATAR);
|
|
||||||
else
|
|
||||||
mAvatar = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,19 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
PlayerData::PlayerData(){
|
||||||
|
init();
|
||||||
|
}
|
||||||
PlayerData::PlayerData(MTGAllCards * allcards){
|
PlayerData::PlayerData(MTGAllCards * allcards){
|
||||||
|
init();
|
||||||
|
|
||||||
|
//COLLECTION
|
||||||
|
if (allcards) collection = NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), allcards);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerData::init() {
|
||||||
|
collection = NULL;
|
||||||
|
|
||||||
//CREDITS
|
//CREDITS
|
||||||
credits = 3000; //Default value
|
credits = 3000; //Default value
|
||||||
|
|
||||||
@@ -17,23 +29,50 @@ PlayerData::PlayerData(MTGAllCards * allcards){
|
|||||||
}else{
|
}else{
|
||||||
//TODO error management
|
//TODO error management
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Story Saves
|
||||||
|
while(std::getline(file,s)){
|
||||||
|
if (!s.size())
|
||||||
|
continue;
|
||||||
|
if (s[s.size()-1] == '\r') s.erase(s.size()-1); //Handle DOS files
|
||||||
|
if (s.size() && s[0] == '#')
|
||||||
|
continue;
|
||||||
|
size_t i = s.find_first_of("=");
|
||||||
|
if (i == string::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string key = s.substr(0,i);
|
||||||
|
string value = s.substr(i+1);
|
||||||
|
if (key.size() < 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(key[0] != 's')
|
||||||
|
continue;
|
||||||
|
key = key.substr(2);
|
||||||
|
storySaves[key]=value;
|
||||||
|
}
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
//COLLECTION
|
|
||||||
collection = NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), allcards);
|
|
||||||
taskList = NEW TaskList(options.profileFile(PLAYER_TASKS).c_str());
|
taskList = NEW TaskList(options.profileFile(PLAYER_TASKS).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int PlayerData::save(){
|
int PlayerData::save(){
|
||||||
std::ofstream file(options.profileFile(PLAYER_SAVEFILE).c_str());
|
std::ofstream file(options.profileFile(PLAYER_SAVEFILE).c_str());
|
||||||
char writer[64];
|
char writer[512];
|
||||||
if (file){
|
if (file){
|
||||||
sprintf(writer,"%i\n", credits);
|
sprintf(writer,"%i\n", credits);
|
||||||
file<<writer;
|
file<<writer;
|
||||||
|
|
||||||
|
//Story Saves
|
||||||
|
for (map<string,string>::iterator it =storySaves.begin(); it !=storySaves.end(); ++it){
|
||||||
|
sprintf(writer,"s %s=%s\n", it->first.c_str(),it->second.c_str());
|
||||||
|
file << writer;
|
||||||
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
collection->save();
|
if (collection) collection->save();
|
||||||
taskList->save();
|
taskList->save();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ MTGCardInstance * Rules::getCardByMTGId(int mtgid){
|
|||||||
RulesPlayerData::RulesPlayerData(){
|
RulesPlayerData::RulesPlayerData(){
|
||||||
life = 20;
|
life = 20;
|
||||||
manapool = NEW ManaCost();
|
manapool = NEW ManaCost();
|
||||||
|
avatar = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
RulesPlayerData::~RulesPlayerData(){
|
RulesPlayerData::~RulesPlayerData(){
|
||||||
@@ -55,7 +56,7 @@ void RulesPlayerZone::add(int cardId){
|
|||||||
|
|
||||||
RulesState::RulesState(){
|
RulesState::RulesState(){
|
||||||
phase = Constants::MTG_PHASE_FIRSTMAIN;
|
phase = Constants::MTG_PHASE_FIRSTMAIN;
|
||||||
|
player = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RulesState::parsePlayerState(int playerId, string s){
|
void RulesState::parsePlayerState(int playerId, string s){
|
||||||
@@ -76,6 +77,9 @@ void RulesState::parsePlayerState(int playerId, string s){
|
|||||||
}else if(areaS.compare("life") == 0){
|
}else if(areaS.compare("life") == 0){
|
||||||
playerData[playerId].life = atoi((s.substr(limiter+1)).c_str());
|
playerData[playerId].life = atoi((s.substr(limiter+1)).c_str());
|
||||||
return;
|
return;
|
||||||
|
}else if(areaS.compare("avatar") == 0){
|
||||||
|
playerData[playerId].avatar = s.substr(limiter+1);
|
||||||
|
return;
|
||||||
}else if(areaS.compare("manapool") == 0){
|
}else if(areaS.compare("manapool") == 0){
|
||||||
SAFE_DELETE(playerData[playerId].manapool);
|
SAFE_DELETE(playerData[playerId].manapool);
|
||||||
playerData[playerId].manapool = ManaCost::parseManaCost(s.substr(limiter+1));
|
playerData[playerId].manapool = ManaCost::parseManaCost(s.substr(limiter+1));
|
||||||
@@ -256,12 +260,23 @@ void Rules::initGame(){
|
|||||||
//Put the GameObserver in the initial state
|
//Put the GameObserver in the initial state
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
OutputDebugString("RULES Init Game\n");
|
OutputDebugString("RULES Init Game\n");
|
||||||
g->phaseRing->goToPhase(initState.phase, g->players[0]);
|
|
||||||
|
//Set the current player/phase
|
||||||
|
g->currentPlayer = g->players[initState.player];
|
||||||
|
g->currentActionPlayer = g->currentPlayer;
|
||||||
|
g->currentPlayerId = initState.player;
|
||||||
|
g->phaseRing->goToPhase(0, g->currentPlayer, false);
|
||||||
|
g->phaseRing->goToPhase(initState.phase, g->currentPlayer);
|
||||||
g->currentGamePhase = initState.phase;
|
g->currentGamePhase = initState.phase;
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++){
|
for (int i = 0; i < 2; i++){
|
||||||
Player * p = g->players[i];
|
Player * p = g->players[i];
|
||||||
p->life = initState.playerData[i].life;
|
p->life = initState.playerData[i].life;
|
||||||
p->getManaPool()->copy(initState.playerData[i].manapool);
|
p->getManaPool()->copy(initState.playerData[i].manapool);
|
||||||
|
if (initState.playerData[i].avatar.size()) {
|
||||||
|
p->loadAvatar(initState.playerData[i].avatar);
|
||||||
|
}
|
||||||
MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay};
|
MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay};
|
||||||
for (int j = 0; j < 4; j++){
|
for (int j = 0; j < 4; j++){
|
||||||
MTGGameZone * zone = playerZones[j];
|
MTGGameZone * zone = playerZones[j];
|
||||||
@@ -371,6 +386,8 @@ int Rules::load(string _filename){
|
|||||||
extraRules.push_back(s.substr(5));
|
extraRules.push_back(s.substr(5));
|
||||||
}else if (s.find("mode=") == 0) {
|
}else if (s.find("mode=") == 0) {
|
||||||
gamemode = strToGameMode(s.substr(5));
|
gamemode = strToGameMode(s.substr(5));
|
||||||
|
}else if (s.find("player=") == 0) {
|
||||||
|
initState.player = atoi(s.substr(7).c_str())-1;
|
||||||
}else{
|
}else{
|
||||||
initState.phase = PhaseRing::phaseStrToInt(s);
|
initState.phase = PhaseRing::phaseStrToInt(s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "../include/WResourceManager.h"
|
#include "../include/WResourceManager.h"
|
||||||
#include "../include/AIPlayer.h"
|
#include "../include/AIPlayer.h"
|
||||||
#include "../include/Rules.h"
|
#include "../include/Rules.h"
|
||||||
|
#include "../include/Credits.h"
|
||||||
|
#include "../include/PlayerData.h"
|
||||||
#include <JLBFont.h>
|
#include <JLBFont.h>
|
||||||
#include <JGE.h>
|
#include <JGE.h>
|
||||||
#include <JFileSystem.h>
|
#include <JFileSystem.h>
|
||||||
@@ -14,6 +16,8 @@
|
|||||||
|
|
||||||
float StoryDialog::currentY = 2;
|
float StoryDialog::currentY = 2;
|
||||||
float StoryDialog::previousY = 2;
|
float StoryDialog::previousY = 2;
|
||||||
|
bool StoryReward::rewardSoundPlayed = false;
|
||||||
|
bool StoryReward::rewardsEnabled = true;
|
||||||
|
|
||||||
StoryDialogElement::StoryDialogElement(float x, float y, int id): JGuiObject(id), mX(x),mY(y) {
|
StoryDialogElement::StoryDialogElement(float x, float y, int id): JGuiObject(id), mX(x),mY(y) {
|
||||||
}
|
}
|
||||||
@@ -49,6 +53,70 @@ float StoryText::getHeight() {
|
|||||||
//Nothing for now
|
//Nothing for now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StoryReward::StoryReward(string _type, string _value, string text, float _mX, float _mY, string _align, int _font, int id):StoryText(text,_mX,_mY, _align, _font, id) {
|
||||||
|
type = STORY_REWARD_CREDITS;
|
||||||
|
if (_type.compare("unlockset") == 0) {
|
||||||
|
type = STORY_REWARD_SET;
|
||||||
|
}
|
||||||
|
value = _value;
|
||||||
|
rewardDone = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoryReward::Render(){
|
||||||
|
if (rewardDone <=0)
|
||||||
|
return;
|
||||||
|
StoryText::Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoryReward::Update(float dt){
|
||||||
|
if (rewardDone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
switch (type){
|
||||||
|
case STORY_REWARD_CREDITS:
|
||||||
|
result = Credits::addCreditBonus(atoi(value.c_str()));
|
||||||
|
break;
|
||||||
|
case STORY_REWARD_SET:
|
||||||
|
{
|
||||||
|
result = Credits::unlockRandomSet(true);
|
||||||
|
MTGSetInfo * si = setlist.getInfo(result - 1);
|
||||||
|
if(si) {
|
||||||
|
string unlockedString = si->getName();
|
||||||
|
size_t pos = text.find("${SET}");
|
||||||
|
if (pos != string::npos) {
|
||||||
|
text.replace(pos,pos + 6,unlockedString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
rewardDone = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rewardsEnabled) {
|
||||||
|
rewardDone = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rewardSoundPlayed && options[Options::SFXVOLUME].number > 0){
|
||||||
|
JSample * sample = resources.RetrieveSample("bonus.wav");
|
||||||
|
if (sample){
|
||||||
|
JSoundSystem::GetInstance()->PlaySample(sample);
|
||||||
|
}
|
||||||
|
rewardSoundPlayed = 1;
|
||||||
|
}
|
||||||
|
rewardDone = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ostream& StoryText::toString(ostream& out) const
|
ostream& StoryText::toString(ostream& out) const
|
||||||
{
|
{
|
||||||
return out << "StoryText ::: text : " << text;
|
return out << "StoryText ::: text : " << text;
|
||||||
@@ -90,15 +158,6 @@ StoryPage::StoryPage(StoryFlow * mParent):mParent(mParent){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StoryFlow::StoryFlow(string folder): folder(folder){
|
|
||||||
string path = "campaigns/";
|
|
||||||
path.append(folder).append("/story.xml");
|
|
||||||
parse(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void StoryChoice::Render()
|
void StoryChoice::Render()
|
||||||
{
|
{
|
||||||
JLBFont * mFont = resources.GetJLBFont(font);
|
JLBFont * mFont = resources.GetJLBFont(font);
|
||||||
@@ -182,7 +241,7 @@ void StoryDuel::init(){
|
|||||||
players[0] = NEW HumanPlayer(NEW MTGPlayerCards(tempDeck),deckFile,deckFileSmall);
|
players[0] = NEW HumanPlayer(NEW MTGPlayerCards(tempDeck),deckFile,deckFileSmall);
|
||||||
SAFE_DELETE(tempDeck);
|
SAFE_DELETE(tempDeck);
|
||||||
|
|
||||||
sprintf(deckFile,"%s/ennemy_deck.txt", folder);
|
sprintf(deckFile,"%s/opponent_deck.txt", folder);
|
||||||
tempDeck = NEW MTGDeck(deckFile, GameApp::collection);
|
tempDeck = NEW MTGDeck(deckFile, GameApp::collection);
|
||||||
sprintf(deckFileSmall, "campaign_ennemy_%s_%s", mParent->folder.c_str(), pageId.c_str());
|
sprintf(deckFileSmall, "campaign_ennemy_%s_%s", mParent->folder.c_str(), pageId.c_str());
|
||||||
players[1] = NEW AIPlayerBaka(NEW MTGPlayerCards(tempDeck),deckFile,deckFileSmall,"baka.jpg");
|
players[1] = NEW AIPlayerBaka(NEW MTGPlayerCards(tempDeck),deckFile,deckFileSmall,"baka.jpg");
|
||||||
@@ -293,6 +352,10 @@ StoryDialog::StoryDialog(TiXmlElement* root, StoryFlow * mParent):StoryPage(mPar
|
|||||||
StoryChoice * sc = NEW StoryChoice(id,text,i,x, y , align, font, (i==0));
|
StoryChoice * sc = NEW StoryChoice(id,text,i,x, y , align, font, (i==0));
|
||||||
graphics.push_back(sc);
|
graphics.push_back(sc);
|
||||||
Add(sc);
|
Add(sc);
|
||||||
|
}else if (strcmp(element->Value(), "reward")==0){
|
||||||
|
string type = safeAttribute(element,"type");
|
||||||
|
string value = safeAttribute(element,"value");
|
||||||
|
graphics.push_back(NEW StoryReward(type, value, text,x,y,align, font));
|
||||||
}else {
|
}else {
|
||||||
//Error
|
//Error
|
||||||
}
|
}
|
||||||
@@ -330,7 +393,7 @@ void StoryDialog::Render() {
|
|||||||
previousY = currentY;
|
previousY = currentY;
|
||||||
for (size_t i = 0; i < graphics.size(); ++i){
|
for (size_t i = 0; i < graphics.size(); ++i){
|
||||||
StoryDialogElement * elmt = (StoryDialogElement *)(graphics[i]);
|
StoryDialogElement * elmt = (StoryDialogElement *)(graphics[i]);
|
||||||
if (elmt == mObjects[0])
|
if (mCount && elmt == mObjects[0])
|
||||||
currentY += SPACE_BEFORE_CHOICES;
|
currentY += SPACE_BEFORE_CHOICES;
|
||||||
RenderElement(elmt);
|
RenderElement(elmt);
|
||||||
}
|
}
|
||||||
@@ -348,6 +411,14 @@ StoryDialog::~StoryDialog(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StoryFlow::StoryFlow(string folder): folder(folder){
|
||||||
|
string path = "campaigns/";
|
||||||
|
path.append(folder).append("/story.xml");
|
||||||
|
parse(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StoryPage * StoryFlow::loadPage(TiXmlElement* element){
|
StoryPage * StoryFlow::loadPage(TiXmlElement* element){
|
||||||
TiXmlNode* typeNode = element->FirstChild("type");
|
TiXmlNode* typeNode = element->FirstChild("type");
|
||||||
if (!typeNode) return NULL;
|
if (!typeNode) return NULL;
|
||||||
@@ -361,12 +432,28 @@ StoryPage * StoryFlow::loadPage(TiXmlElement* element){
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
bool StoryFlow::gotoPage(string id){
|
bool StoryFlow::_gotoPage(string id){
|
||||||
|
StoryReward::rewardSoundPlayed = false;
|
||||||
|
if (pages.find(id) == pages.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
currentPageId = id;
|
currentPageId = id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StoryFlow::gotoPage(string id){
|
||||||
|
StoryReward::rewardsEnabled = true;
|
||||||
|
return _gotoPage(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoryFlow::loadPageId(string id) {
|
||||||
|
StoryReward::rewardsEnabled = false;
|
||||||
|
return _gotoPage(id);
|
||||||
|
}
|
||||||
|
|
||||||
bool StoryFlow::parse(string path)
|
bool StoryFlow::parse(string path)
|
||||||
{
|
{
|
||||||
JFileSystem *fileSystem = JFileSystem::GetInstance();
|
JFileSystem *fileSystem = JFileSystem::GetInstance();
|
||||||
@@ -399,6 +486,15 @@ bool StoryFlow::parse(string path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//autoLoad
|
||||||
|
PlayerData * pd = NEW PlayerData();
|
||||||
|
map<string,string>::iterator it = pd->storySaves.find(folder);
|
||||||
|
if (it!=pd->storySaves.end()) {
|
||||||
|
if (it->second.compare("End") !=0)
|
||||||
|
loadPageId(it->second);
|
||||||
|
}
|
||||||
|
SAFE_DELETE(pd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,4 +513,10 @@ StoryFlow::~StoryFlow(){
|
|||||||
SAFE_DELETE(i->second);
|
SAFE_DELETE(i->second);
|
||||||
}
|
}
|
||||||
pages.clear();
|
pages.clear();
|
||||||
|
|
||||||
|
//autoSave progress
|
||||||
|
PlayerData * pd = NEW PlayerData();
|
||||||
|
pd->storySaves[folder] = currentPageId;
|
||||||
|
pd->save();
|
||||||
|
SAFE_DELETE(pd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -586,13 +586,17 @@ string WResourceManager::avatarFile(const string filename){
|
|||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
//Failure. Check graphics
|
//Failure. Check graphics
|
||||||
char graphdir[512];
|
sprintf(buf,"graphics/%s",filename.c_str());
|
||||||
sprintf(graphdir,"graphics/%s",filename.c_str());
|
if(fileOK(buf,true))
|
||||||
if(fileOK(graphdir,true))
|
return buf;
|
||||||
return graphdir;
|
|
||||||
|
//Failure. Check raw faile.
|
||||||
|
sprintf(buf,"%s",filename.c_str());
|
||||||
|
if(fileOK(buf,true))
|
||||||
|
return buf;
|
||||||
|
|
||||||
//Complete abject failure. Probably a crash...
|
//Complete abject failure. Probably a crash...
|
||||||
return graphdir;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
string WResourceManager::cardFile(const string filename){
|
string WResourceManager::cardFile(const string filename){
|
||||||
|
|||||||
Reference in New Issue
Block a user