Typo in successful Lux Cannon so that the AI can use the destroy ability Throatseeker Icingdeath, Frost Tyrant you don't "cast" the token Insubordination Infectious Curse Igneous Elemental Abu Jafar both? _ETERNALIZE_
1079 lines
32 KiB
C++
1079 lines
32 KiB
C++
/*
|
|
The shop is where the player can buy cards, decks...
|
|
*/
|
|
#include "PrecompiledHeader.h"
|
|
|
|
#include <JRenderer.h>
|
|
#include "GameStateShop.h"
|
|
#include "GameStateMenu.h"
|
|
#include "GameApp.h"
|
|
#include "MTGDeck.h"
|
|
#include "MTGPack.h"
|
|
#include "Translate.h"
|
|
#include "TestSuiteAI.h"
|
|
|
|
#include <hge/hgedistort.h>
|
|
#include "WFont.h"
|
|
|
|
float GameStateShop::_x1[] = { 79, 19, 27, 103, 154, 187, 102, 144, 198, 133, 183 };
|
|
float GameStateShop::_y1[] = { 150, 194, 222, 167, 164, 156, 195, 190, 175, 220, 220 };
|
|
|
|
float GameStateShop::_x2[] = { 103, 48, 74, 135, 183, 215, 138, 181, 231, 171, 225 };
|
|
float GameStateShop::_y2[] = { 155, 179, 218, 165, 166, 155, 195, 186, 177, 225, 216 };
|
|
|
|
float GameStateShop::_x3[] = { 48, 61, 9, 96, 139, 190, 81, 146, 187, 97, 191 };
|
|
float GameStateShop::_y3[] = { 164, 205, 257, 184, 180, 170, 219, 212, 195, 251, 252 };
|
|
|
|
float GameStateShop::_x4[] = { 76, 90, 65, 131, 171, 221, 123, 187, 225, 141, 237 };
|
|
float GameStateShop::_y4[] = { 169, 188, 250, 182, 182, 168, 220, 208, 198, 259, 245 };
|
|
|
|
namespace
|
|
{
|
|
#ifndef TOUCH_ENABLED
|
|
float kPspIconScaleFactor = 0.5f;
|
|
#endif // TOUCH_ENABLED
|
|
std::string kOtherCardsString(": Other cards");
|
|
std::string kCreditsString("Credits: ");
|
|
}
|
|
|
|
|
|
BoosterDisplay::BoosterDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener, TargetChooser * tc,
|
|
int nb_displayed_items) :
|
|
CardDisplay(id, game, x, y, listener, tc, nb_displayed_items)
|
|
{
|
|
}
|
|
|
|
bool BoosterDisplay::CheckUserInput(JButton key)
|
|
{
|
|
if (JGE_BTN_UP == key || JGE_BTN_DOWN == key || JGE_BTN_PRI == key)
|
|
return false;
|
|
|
|
return CardDisplay::CheckUserInput(key);
|
|
|
|
}
|
|
|
|
GameStateShop::GameStateShop(GameApp* parent) :
|
|
GameState(parent, "shop")
|
|
{
|
|
menu = NULL;
|
|
boosterDisplay = NULL;
|
|
taskList = NULL;
|
|
srcCards = NULL;
|
|
shopMenu = NULL;
|
|
bigDisplay = NULL;
|
|
myCollection = NULL;
|
|
packlist = NULL;
|
|
pricelist = NULL;
|
|
playerdata = NULL;
|
|
booster = NULL;
|
|
lightAlpha = 0;
|
|
filterMenu = NULL;
|
|
alphaChange = 0;
|
|
for (int i = 0; i < SHOP_ITEMS; i++)
|
|
{
|
|
mPrices[i] = 0;
|
|
mCounts[i] = 0;
|
|
}
|
|
mTouched = false;
|
|
|
|
kOtherCardsString = _(kOtherCardsString);
|
|
kCreditsString = _(kCreditsString);
|
|
|
|
cycleCardsButton = NEW InteractiveButton(NULL, kCycleCardsButtonId, Fonts::MAIN_FONT, "New Cards", SCREEN_WIDTH_F - 80, SCREEN_HEIGHT_F - 20, JGE_BTN_PRI);
|
|
|
|
showCardListButton = NEW InteractiveButton(NULL, kShowCardListButtonId, Fonts::MAIN_FONT, "Show List", SCREEN_WIDTH_F - 150, SCREEN_HEIGHT_F - 20, JGE_BTN_SEC);
|
|
disablePurchase = false;
|
|
clearInput = false;
|
|
}
|
|
|
|
GameStateShop::~GameStateShop()
|
|
{
|
|
SAFE_DELETE( cycleCardsButton );
|
|
SAFE_DELETE( showCardListButton );
|
|
End();
|
|
}
|
|
|
|
void GameStateShop::Create()
|
|
{
|
|
}
|
|
|
|
void GameStateShop::Start()
|
|
{
|
|
menu = NULL;
|
|
bListCards = false;
|
|
mTouched = false;
|
|
mStage = STAGE_FADE_IN;
|
|
needLoad = true;
|
|
booster = NULL;
|
|
srcCards = NEW WSrcUnlockedCards(0);
|
|
srcCards->setElapsed(15);
|
|
srcCards->addFilter(NEW WCFilterNOT(NEW WCFilterRarity("T")));
|
|
srcCards->addFilter(NEW WCFilterNOT(NEW WCFilterSet(MTGSets::INTERNAL_SET)));
|
|
|
|
shopMenu = NEW WGuiMenu(JGE_BTN_DOWN, JGE_BTN_UP, true, &bigSync);
|
|
MTGAllCards * ac = MTGCollection();
|
|
playerdata = NEW PlayerData(ac);
|
|
myCollection = NEW DeckDataWrapper(playerdata->collection);
|
|
pricelist = NEW PriceList("settings/prices.dat", ac);
|
|
for (int i = 0; i < SHOP_SLOTS; i++)
|
|
{
|
|
WGuiCardDistort * dist;
|
|
if (i < BOOSTER_SLOTS)
|
|
dist = NEW WGuiCardDistort(NULL, true);
|
|
else
|
|
{
|
|
dist = NEW WGuiCardDistort(srcCards, true);
|
|
dist->mOffset.setOffset(i - BOOSTER_SLOTS);
|
|
}
|
|
dist->xy = WDistort(_x1[i], _y1[i], _x2[i], _y2[i], _x3[i], _y3[i], _x4[i], _y4[i]);
|
|
shopMenu->Add(NEW WGuiButton(dist, -102, i, this));
|
|
}
|
|
shopMenu->Entering(JGE_BTN_NONE);
|
|
|
|
if (!bigDisplay)
|
|
{
|
|
bigDisplay = NEW WGuiCardImage(srcCards);
|
|
bigDisplay->mOffset.Hook(&bigSync);
|
|
bigDisplay->mOffset.setOffset(-BOOSTER_SLOTS);
|
|
bigDisplay->setX(385);
|
|
bigDisplay->setY(135);
|
|
}
|
|
|
|
for (int i = 0; i < 8; ++i)
|
|
{
|
|
std::ostringstream stream;
|
|
stream << "iconspsp" << i;
|
|
pspIcons[i] = WResourceManager::Instance()->RetrieveQuad("iconspsp.png", (float) i * 32, 0, 32, 32, stream.str(), RETRIEVE_MANAGE);
|
|
pspIcons[i]->SetHotSpot(16, 16);
|
|
}
|
|
|
|
#if !defined (PSP)
|
|
GameApp::playMusic("Track2.mp3"); // Added music for shop.
|
|
#endif
|
|
|
|
JRenderer::GetInstance()->EnableVSync(true);
|
|
|
|
taskList = NULL;
|
|
packlist = NEW MTGPacks();
|
|
packlist->loadAll();
|
|
load();
|
|
}
|
|
|
|
string GameStateShop::descPurchase(int controlId, bool tiny)
|
|
{
|
|
char buffer[4096];
|
|
string name;
|
|
if (controlId < BOOSTER_SLOTS)
|
|
{
|
|
name = mBooster[controlId].getName();
|
|
}
|
|
else
|
|
{
|
|
MTGCard * c = srcCards->getCard(controlId - BOOSTER_SLOTS);
|
|
if (!c)
|
|
return "";
|
|
name = _(c->data->getName());
|
|
}
|
|
if (mInventory[controlId] <= 0)
|
|
{
|
|
if (tiny)
|
|
sprintf(buffer, _("SOLD OUT").c_str(), name.c_str());
|
|
else
|
|
sprintf(buffer, _("%s : SOLD OUT").c_str(), name.c_str());
|
|
return buffer;
|
|
}
|
|
|
|
if (tiny)
|
|
{
|
|
if (controlId < BOOSTER_SLOTS || mCounts[controlId] == 0)
|
|
return name;
|
|
|
|
sprintf(buffer, _("%s (%i)").c_str(), name.c_str(), mCounts[controlId]);
|
|
return buffer;
|
|
}
|
|
switch (options[Options::ECON_DIFFICULTY].number)
|
|
{
|
|
case Constants::ECON_HARD:
|
|
case Constants::ECON_NORMAL:
|
|
if (mCounts[controlId] < 1)
|
|
sprintf(buffer, _("%s").c_str(), name.c_str());
|
|
else
|
|
sprintf(buffer, _("%s (%i)").c_str(), name.c_str(), mCounts[controlId]);
|
|
break;
|
|
default:
|
|
if (mCounts[controlId] < 1)
|
|
sprintf(buffer, _("%s : %i credits").c_str(), name.c_str(), mPrices[controlId]);
|
|
else
|
|
sprintf(buffer, _("%s (%i) : %i credits").c_str(), name.c_str(), mCounts[controlId], mPrices[controlId]);
|
|
break;
|
|
}
|
|
return buffer;
|
|
}
|
|
void GameStateShop::beginPurchase(int controlId)
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MENU_FONT);
|
|
mFont->SetScale(SCALE_NORMAL);
|
|
SAFE_DELETE(menu);
|
|
if (mInventory[controlId] <= 0)
|
|
{
|
|
menu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), -145, this, Fonts::MENU_FONT, SCREEN_WIDTH - 300, SCREEN_HEIGHT / 2, _("Sold Out").c_str());
|
|
menu->Add(-1, "Ok");
|
|
}
|
|
else if (playerdata->credits - mPrices[controlId] < 0)
|
|
{
|
|
menu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), -145, this, Fonts::MENU_FONT, SCREEN_WIDTH - 300, SCREEN_HEIGHT / 2, _("Not enough credits").c_str());
|
|
menu->Add(-1, "Ok");
|
|
if (options[Options::CHEATMODE].number)
|
|
{
|
|
menu->Add(-2, _("Steal it").c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char buf[512];
|
|
if (controlId < BOOSTER_SLOTS)
|
|
sprintf(buf, _("Purchase Booster: %i credits").c_str(), mPrices[controlId]);
|
|
else
|
|
sprintf(buf, _("Purchase Card: %i credits").c_str(), mPrices[controlId]);
|
|
menu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), -145, this, Fonts::MENU_FONT, SCREEN_WIDTH - 300, SCREEN_HEIGHT / 2, buf);
|
|
|
|
menu->Add(controlId, "Yes");
|
|
menu->Add(-1, "No");
|
|
}
|
|
}
|
|
void GameStateShop::cancelCard(int controlId)
|
|
{
|
|
//Update prices
|
|
MTGCard * c = srcCards->getCard(controlId - BOOSTER_SLOTS);
|
|
if (!c || !c->data || playerdata->credits - mPrices[controlId] < 0)
|
|
return; //We only care about their opinion if they /can/ buy it.
|
|
|
|
int price = mPrices[controlId];
|
|
int rnd;
|
|
switch (options[Options::ECON_DIFFICULTY].number)
|
|
{
|
|
case Constants::ECON_HARD:
|
|
rnd = rand() % 10;
|
|
break;
|
|
case Constants::ECON_EASY:
|
|
rnd = rand() % 50;
|
|
break;
|
|
default:
|
|
rnd = rand() % 25;
|
|
break;
|
|
}
|
|
price = price - (rnd * price) / 100;
|
|
if (price < pricelist->getPrice(c)) //filters have a tendancy to increase the price instead of lowering it!
|
|
pricelist->setPrice(c, price);
|
|
//Prices do not immediately go down when you ignore something.
|
|
return;
|
|
}
|
|
void GameStateShop::cancelBooster(int)
|
|
{
|
|
return; //TODO FIXME Tie boosters into pricelist.
|
|
}
|
|
void GameStateShop::purchaseCard(int controlId)
|
|
{
|
|
MTGCard * c = srcCards->getCard(controlId - BOOSTER_SLOTS);
|
|
if (!c || !c->data || playerdata->credits - mPrices[controlId] < 0 || (c && c->getRarity() == Constants::RARITY_T))//cant buy tokens....
|
|
return;
|
|
myCollection->Add(c);
|
|
int price = mPrices[controlId];
|
|
pricelist->setPrice(c->getMTGId(), price); // In case they changed their minds after cancelling.
|
|
playerdata->credits -= price;
|
|
GameApp::mycredits = playerdata->credits;
|
|
//Update prices
|
|
int rnd;
|
|
switch (options[Options::ECON_DIFFICULTY].number)
|
|
{
|
|
case Constants::ECON_HARD:
|
|
rnd = rand() % 50;
|
|
break;
|
|
case Constants::ECON_EASY:
|
|
rnd = rand() % 10;
|
|
break;
|
|
default:
|
|
rnd = rand() % 25;
|
|
break;
|
|
}
|
|
price = price + (rnd * price) / 100;
|
|
pricelist->setPrice(c->getMTGId(), price);
|
|
mPrices[controlId] = pricelist->getPurchasePrice(c->getMTGId()); //Prices go up immediately.
|
|
mInventory[controlId]--;
|
|
updateCounts();
|
|
mTouched = true;
|
|
menu->Close();
|
|
}
|
|
void GameStateShop::purchaseBooster(int controlId)
|
|
{
|
|
if (playerdata->credits - mPrices[controlId] < 0)
|
|
return;
|
|
playerdata->credits -= mPrices[controlId];
|
|
GameApp::mycredits = playerdata->credits;
|
|
mInventory[controlId]--;
|
|
SAFE_DELETE(booster);
|
|
deleteDisplay();
|
|
booster = NEW MTGDeck(MTGCollection());
|
|
boosterDisplay = NEW BoosterDisplay(12, NULL, SCREEN_WIDTH - 255, SCREEN_HEIGHT-65, this, NULL, 7);
|
|
mBooster[controlId].addToDeck(booster, srcCards);
|
|
|
|
string sort = mBooster[controlId].getSort();
|
|
DeckDataWrapper * ddw = NEW DeckDataWrapper(booster);
|
|
if (sort == "alpha")
|
|
ddw->Sort(WSrcCards::SORT_ALPHA);
|
|
else if (sort == "collector")
|
|
ddw->Sort(WSrcCards::SORT_COLLECTOR);
|
|
else
|
|
ddw->Sort(WSrcCards::SORT_RARITY);
|
|
|
|
for (int x = 0; x < ddw->Size(); x++)
|
|
{
|
|
MTGCard * c = ddw->getCard(x);
|
|
for (int copies = 0; copies < ddw->count(c); ++copies)
|
|
{
|
|
MTGCardInstance * ci = NEW MTGCardInstance(c, NULL);
|
|
boosterDisplay->AddCard(ci);
|
|
subBooster.push_back(ci);
|
|
}
|
|
}
|
|
SAFE_DELETE(ddw);
|
|
|
|
myCollection->loadMatches(booster);
|
|
mTouched = true;
|
|
save(true);
|
|
menu->Close();
|
|
}
|
|
|
|
int GameStateShop::purchasePrice(int offset)
|
|
{
|
|
MTGCard * c = NULL;
|
|
if (!pricelist || !srcCards || (c = srcCards->getCard(offset)) == NULL)
|
|
return 0;
|
|
float price = (float) pricelist->getPurchasePrice(c->getMTGId());
|
|
int filteradd = srcCards->Size(true);
|
|
filteradd = ((filteradd - srcCards->Size()) / filteradd);
|
|
|
|
switch (options[Options::ECON_DIFFICULTY].number)
|
|
{
|
|
case Constants::ECON_EASY:
|
|
filteradd /= 2;
|
|
break;
|
|
case Constants::ECON_HARD:
|
|
filteradd *= 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return (int) (price + price * (filteradd * srcCards->filterFee()));
|
|
}
|
|
void GameStateShop::updateCounts()
|
|
{
|
|
for (int i = BOOSTER_SLOTS; i < SHOP_ITEMS; i++)
|
|
{
|
|
MTGCard * c = srcCards->getCard(i - BOOSTER_SLOTS);
|
|
if (!c)
|
|
mCounts[i] = 0;
|
|
else
|
|
mCounts[i] = myCollection->countByName(c);
|
|
}
|
|
}
|
|
void GameStateShop::load()
|
|
{
|
|
for (int i = 0; i < BOOSTER_SLOTS; i++)
|
|
{
|
|
mBooster[i].randomize(packlist);
|
|
mInventory[i] = 1 + rand() % mBooster[i].maxInventory();
|
|
mPrices[i] = pricelist->getOtherPrice(mBooster[i].basePrice());
|
|
}
|
|
for (int i = BOOSTER_SLOTS; i < SHOP_ITEMS; i++)
|
|
{
|
|
MTGCard * c = NULL;
|
|
if ((c = srcCards->getCard(i - BOOSTER_SLOTS)) == NULL)
|
|
{
|
|
mPrices[i] = 0;
|
|
mCounts[i] = 0;
|
|
mInventory[i] = 0;
|
|
continue;
|
|
}
|
|
mPrices[i] = purchasePrice(i - BOOSTER_SLOTS);
|
|
mCounts[i] = myCollection->countByName(c);
|
|
switch (c->getRarity())
|
|
{
|
|
case Constants::RARITY_C:
|
|
mInventory[i] = 2 + rand() % 8;
|
|
break;
|
|
case Constants::RARITY_L:
|
|
mInventory[i] = 100;
|
|
break;
|
|
default: //We're using some non-coded rarities (S) in cards.dat.
|
|
case Constants::RARITY_U:
|
|
mInventory[i] = 1 + rand() % 5;
|
|
break;
|
|
case Constants::RARITY_R:
|
|
mInventory[i] = 1 + rand() % 2;
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
void GameStateShop::save(bool force)
|
|
{
|
|
if (mTouched || force)
|
|
{
|
|
if (myCollection)
|
|
myCollection->Rebuild(playerdata->collection);
|
|
if (playerdata)
|
|
playerdata->save();
|
|
if (pricelist)
|
|
pricelist->save();
|
|
}
|
|
mTouched = false;
|
|
}
|
|
void GameStateShop::End()
|
|
{
|
|
save();
|
|
JRenderer::GetInstance()->EnableVSync(false);
|
|
|
|
SAFE_DELETE(shopMenu);
|
|
SAFE_DELETE(bigDisplay);
|
|
SAFE_DELETE(srcCards);
|
|
SAFE_DELETE(playerdata);
|
|
SAFE_DELETE(pricelist);
|
|
SAFE_DELETE(myCollection);
|
|
SAFE_DELETE(booster);
|
|
SAFE_DELETE(filterMenu);
|
|
SAFE_DELETE(packlist);
|
|
deleteDisplay();
|
|
|
|
SAFE_DELETE(menu);
|
|
SAFE_DELETE(taskList);
|
|
}
|
|
|
|
void GameStateShop::Destroy()
|
|
{
|
|
}
|
|
void GameStateShop::beginFilters()
|
|
{
|
|
if (!filterMenu)
|
|
{
|
|
filterMenu = NEW WGuiFilters("Ask about...", srcCards);
|
|
filterMenu->setY(2);
|
|
filterMenu->setHeight(SCREEN_HEIGHT - 2);
|
|
}
|
|
mStage = STAGE_ASK_ABOUT;
|
|
filterMenu->Entering(JGE_BTN_NONE);
|
|
}
|
|
void GameStateShop::Update(float dt)
|
|
{
|
|
if (menu && menu->isClosed())
|
|
SAFE_DELETE(menu);
|
|
srcCards->Update(dt);
|
|
alphaChange = 25 - static_cast<int>((float) (rand() - 1) / (RAND_MAX) * 50.0f);
|
|
lightAlpha += alphaChange;
|
|
if (lightAlpha < 0)
|
|
lightAlpha = 0;
|
|
if (lightAlpha > 50)
|
|
lightAlpha = 50;
|
|
|
|
JButton btn;
|
|
switch (mStage)
|
|
{
|
|
case STAGE_SHOP_PURCHASE:
|
|
if (menu)
|
|
menu->Update(dt);
|
|
beginPurchase(mBuying);
|
|
mStage = STAGE_SHOP_SHOP;
|
|
break;
|
|
case STAGE_SHOP_MENU:
|
|
if (menu)
|
|
menu->Update(dt);
|
|
else
|
|
{
|
|
menu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), 11, this, Fonts::MENU_FONT, SCREEN_WIDTH / 2 - 100, 20);
|
|
menu->Add(22, _("Ask about...").c_str());
|
|
menu->Add(14, _("Check task board").c_str());
|
|
if (options[Options::CHEATMODE].number)
|
|
menu->Add(-2, _("Steal 2,000 credits").c_str());
|
|
menu->Add(12, _("Save And Exit").c_str());
|
|
menu->Add(kCancelMenuID, _("Cancel").c_str());
|
|
}
|
|
break;
|
|
case STAGE_SHOP_TASKS:
|
|
if (menu && !menu->isClosed())
|
|
{
|
|
menu->Update(dt);
|
|
return;
|
|
}
|
|
if (taskList)
|
|
{
|
|
btn = mEngine->ReadButton();
|
|
taskList->Update(dt);
|
|
if (taskList->getState() != TaskList::TASKS_INACTIVE)
|
|
{
|
|
if (btn == JGE_BTN_SEC || btn == JGE_BTN_CANCEL || btn == JGE_BTN_PREV)
|
|
{
|
|
taskList->End();
|
|
return;
|
|
}
|
|
else if (taskList->getState() == TaskList::TASKS_ACTIVE && btn == JGE_BTN_MENU)
|
|
{
|
|
if (!menu)
|
|
{
|
|
menu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), 11, this, Fonts::MENU_FONT, SCREEN_WIDTH / 2 - 100, 20);
|
|
menu->Add(15, "Return to shop");
|
|
menu->Add(12, "Save And Exit");
|
|
menu->Add(kCancelMenuID, "Cancel");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
mStage = STAGE_SHOP_SHOP;
|
|
}
|
|
|
|
#ifdef TESTSUITE
|
|
if ((mEngine->GetButtonClick(JGE_BTN_PRI)) && (taskList))
|
|
{
|
|
taskList->passOneDay();
|
|
if (taskList->getTaskCount() < 6)
|
|
{
|
|
taskList->addRandomTask();
|
|
taskList->addRandomTask();
|
|
}
|
|
taskList->save();
|
|
}
|
|
#endif
|
|
break;
|
|
case STAGE_ASK_ABOUT:
|
|
btn = mEngine->ReadButton();
|
|
if (menu && !menu->isClosed())
|
|
{
|
|
menu->CheckUserInput(btn);
|
|
menu->Update(dt);
|
|
return;
|
|
}
|
|
if (filterMenu)
|
|
{
|
|
if (btn == JGE_BTN_CTRL)
|
|
{
|
|
needLoad = filterMenu->Finish();
|
|
filterMenu->Update(dt);
|
|
return;
|
|
}
|
|
if (filterMenu->isFinished())
|
|
{
|
|
if (needLoad)
|
|
{
|
|
srcCards->addFilter(NEW WCFilterNOT(NEW WCFilterRarity("T")));
|
|
srcCards->addFilter(NEW WCFilterNOT(NEW WCFilterSet(MTGSets::INTERNAL_SET)));
|
|
if (!srcCards->Size())
|
|
{
|
|
srcCards->clearFilters(); //Repetition of check at end of filterMenu->Finish(), for the token removal
|
|
srcCards->addFilter(NEW WCFilterNOT(NEW WCFilterRarity("T")));
|
|
srcCards->addFilter(NEW WCFilterNOT(NEW WCFilterSet(MTGSets::INTERNAL_SET)));
|
|
}
|
|
load();
|
|
}
|
|
mStage = STAGE_SHOP_SHOP;
|
|
}
|
|
else
|
|
{
|
|
filterMenu->CheckUserInput(btn);
|
|
filterMenu->Update(dt);
|
|
}
|
|
return;
|
|
}
|
|
break;
|
|
case STAGE_SHOP_SHOP:
|
|
btn = mEngine->ReadButton();
|
|
if (menu && !menu->isClosed())
|
|
{
|
|
menu->CheckUserInput(btn);
|
|
menu->Update(dt);
|
|
return;
|
|
}
|
|
if (btn == JGE_BTN_MENU)
|
|
{
|
|
if (boosterDisplay)
|
|
{
|
|
deleteDisplay();
|
|
return;
|
|
}
|
|
mStage = STAGE_SHOP_MENU;
|
|
return;
|
|
}
|
|
else if (btn == JGE_BTN_CTRL)
|
|
beginFilters();
|
|
else if (btn == JGE_BTN_NEXT)
|
|
{
|
|
mStage = STAGE_SHOP_TASKS;
|
|
if (!taskList)
|
|
taskList = NEW TaskList();
|
|
taskList->Start();
|
|
}
|
|
else if (boosterDisplay)
|
|
{
|
|
if (btn == JGE_BTN_SEC)
|
|
deleteDisplay();
|
|
else
|
|
{
|
|
boosterDisplay->CheckUserInput(btn);
|
|
boosterDisplay->Update(dt);
|
|
}
|
|
return;
|
|
}
|
|
else if (btn == JGE_BTN_PRI) // so we don't shuffle while we view our newly purchased booster display.
|
|
{
|
|
srcCards->Shuffle();
|
|
load();
|
|
disablePurchase = false;
|
|
clearInput = true;
|
|
return;
|
|
|
|
}
|
|
else if (btn == JGE_BTN_CANCEL)
|
|
options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number;
|
|
else if (btn == JGE_BTN_SEC)
|
|
{
|
|
bListCards = !bListCards;
|
|
disablePurchase = false;
|
|
clearInput = true;
|
|
return;
|
|
}
|
|
else if (shopMenu)
|
|
{
|
|
#if defined (IOS) || defined (ANDROID)
|
|
if ((cycleCardsButton->ButtonPressed() || showCardListButton->ButtonPressed()))
|
|
#else
|
|
if ( (btn == JGE_BTN_OK) && (cycleCardsButton->ButtonPressed() || showCardListButton->ButtonPressed()))
|
|
#endif
|
|
{
|
|
disablePurchase = true;
|
|
return;
|
|
}
|
|
else
|
|
#if defined (IOS) || defined (ANDROID)
|
|
if (clearInput && (btn == JGE_BTN_OK))
|
|
{
|
|
clearInput = false;
|
|
disablePurchase = false;
|
|
return;
|
|
}
|
|
else
|
|
#endif
|
|
if (shopMenu->CheckUserInput(btn))
|
|
srcCards->Touch();
|
|
}
|
|
if (shopMenu)
|
|
shopMenu->Update(dt);
|
|
|
|
break;
|
|
case STAGE_FADE_IN:
|
|
mParent->DoAnimation(TRANSITION_FADE_IN);
|
|
mStage = STAGE_SHOP_SHOP;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GameStateShop::deleteDisplay()
|
|
{
|
|
vector<MTGCardInstance*>::iterator i;
|
|
for (i = subBooster.begin(); i != subBooster.end(); i++)
|
|
{
|
|
if (!*i)
|
|
continue;
|
|
delete *i;
|
|
}
|
|
subBooster.clear();
|
|
SAFE_DELETE(boosterDisplay);
|
|
}
|
|
|
|
void GameStateShop::enableButtons()
|
|
{
|
|
cycleCardsButton->setIsSelectionValid(true);
|
|
showCardListButton->setIsSelectionValid(true);
|
|
}
|
|
|
|
void GameStateShop::renderButtons()
|
|
{
|
|
cycleCardsButton->Render();
|
|
showCardListButton->Render();
|
|
}
|
|
|
|
void GameStateShop::Render()
|
|
{
|
|
//Erase
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT);
|
|
JRenderer * r = JRenderer::GetInstance();
|
|
r->ClearScreen(ARGB(0,0,0,0));
|
|
if (mStage == STAGE_FADE_IN)
|
|
return;
|
|
|
|
#if defined (PSP)
|
|
JQuadPtr mBg = WResourceManager::Instance()->RetrieveTempQuad("pspshop.jpg", TEXTURE_SUB_5551);
|
|
if (mBg.get())
|
|
r->RenderQuad(mBg.get(), 0, 0, 0, SCREEN_WIDTH_F / mBg->mWidth, SCREEN_HEIGHT_F / mBg->mHeight);
|
|
|
|
JQuadPtr quad = WResourceManager::Instance()->RetrieveTempQuad("pspshop_light.jpg", TEXTURE_SUB_5551);
|
|
#else
|
|
JQuadPtr mBg = WResourceManager::Instance()->RetrieveTempQuad("shop.jpg", TEXTURE_SUB_5551);
|
|
if (mBg.get())
|
|
r->RenderQuad(mBg.get(), 0, 0, 0, SCREEN_WIDTH_F / mBg->mWidth, SCREEN_HEIGHT_F / mBg->mHeight);
|
|
|
|
JQuadPtr quad = WResourceManager::Instance()->RetrieveTempQuad("shop_light.jpg", TEXTURE_SUB_5551);
|
|
#endif
|
|
|
|
if (quad.get())
|
|
{
|
|
r->EnableTextureFilter(false);
|
|
r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE);
|
|
quad->SetColor(ARGB(lightAlpha,255,255,255));
|
|
quad->SetHotSpot(0,quad->mHeight);
|
|
r->RenderQuad(quad.get(), 0, SCREEN_HEIGHT, 0, 255.f / quad->mWidth, 272.f / quad->mHeight);
|
|
r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA);
|
|
r->EnableTextureFilter(true);
|
|
}
|
|
|
|
if (shopMenu)
|
|
shopMenu->Render();
|
|
|
|
if (filterMenu && !filterMenu->isFinished())
|
|
filterMenu->Render();
|
|
else
|
|
{
|
|
if (boosterDisplay)
|
|
boosterDisplay->Render(true);
|
|
else if (bigDisplay)
|
|
{
|
|
if (bigDisplay->mOffset.getPos() >= 0)
|
|
bigDisplay->setSource(srcCards);
|
|
else
|
|
bigDisplay->setSource(NULL);
|
|
bigDisplay->Render();
|
|
float elp = srcCards->getElapsed();
|
|
//Render the card list overlay.
|
|
if (bListCards || elp > LIST_FADEIN)
|
|
{
|
|
int alpha = 200;
|
|
if (!bListCards && elp < LIST_FADEIN + .25)
|
|
{
|
|
alpha = static_cast<int> (800 * (elp - LIST_FADEIN));
|
|
}
|
|
//r->FillRoundRect(300, 10, 160, SHOP_SLOTS * 20 + 15, 5, ARGB(alpha,0,0,0));
|
|
r->FillRect(297, 9.5f, 175, SHOP_SLOTS * 20 + 31, ARGB(alpha,0,0,0));
|
|
r->DrawRect(297, 9.5f, 175, SHOP_SLOTS * 20 + 31, ARGB(alpha,20,20,20));
|
|
alpha += 55;
|
|
for (int i = 0; i < SHOP_SLOTS; i++)
|
|
{
|
|
if (i == shopMenu->getSelected())
|
|
mFont->SetColor(ARGB(alpha,255,255,0));
|
|
else
|
|
mFont->SetColor(ARGB(alpha,255,255,255));
|
|
char buffer[512];
|
|
string s = descPurchase(i, true);
|
|
sprintf(buffer, "%s", s.c_str());
|
|
float x = 310;
|
|
float y = static_cast<float> (25 + 20 * i);
|
|
mFont->DrawString(buffer, x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Render the info bar
|
|
r->FillRect(0, SCREEN_HEIGHT - 17, SCREEN_WIDTH, 17, ARGB(128,0,0,0));
|
|
std::ostringstream stream;
|
|
stream << kCreditsString << playerdata->credits;
|
|
mFont->SetColor(ARGB(255,255,255,255));
|
|
mFont->DrawString(stream.str(), 5, SCREEN_HEIGHT - 14);
|
|
|
|
#ifndef TOUCH_ENABLED
|
|
float len = 4 + mFont->GetStringWidth(kOtherCardsString.c_str());
|
|
r->RenderQuad(pspIcons[6].get(), SCREEN_WIDTH - len - 0.5 - 10, SCREEN_HEIGHT - 8, 0, kPspIconScaleFactor, kPspIconScaleFactor);
|
|
mFont->DrawString(kOtherCardsString, SCREEN_WIDTH - len, SCREEN_HEIGHT - 14);
|
|
#else
|
|
enableButtons();
|
|
#endif
|
|
|
|
mFont->SetColor(ARGB(255,255,255,0));
|
|
mFont->DrawString(descPurchase(bigSync.getPos()).c_str(), SCREEN_WIDTH / 2, SCREEN_HEIGHT - 14, JGETEXT_CENTER);
|
|
mFont->SetColor(ARGB(255,255,255,255));
|
|
|
|
if (mStage == STAGE_SHOP_TASKS && taskList)
|
|
{
|
|
taskList->Render();
|
|
}
|
|
if (menu)
|
|
menu->Render();
|
|
|
|
if ((!filterMenu || (filterMenu && filterMenu->isFinished()))&&!boosterDisplay)
|
|
renderButtons();
|
|
}
|
|
|
|
void GameStateShop::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
int sel = bigSync.getOffset();
|
|
switch (controllerId)
|
|
{
|
|
case -102: //Buying something...
|
|
mStage = STAGE_SHOP_PURCHASE;
|
|
if (menu)
|
|
menu->Close();
|
|
mBuying = controlId;
|
|
return;
|
|
case -145:
|
|
if (controlId == -1)
|
|
{ //Nope, don't buy.
|
|
if (sel < BOOSTER_SLOTS)
|
|
cancelBooster(sel);
|
|
else
|
|
cancelCard(sel);
|
|
menu->Close();
|
|
mStage = STAGE_SHOP_SHOP;
|
|
return;
|
|
}
|
|
if (sel > -1 && sel < SHOP_ITEMS)
|
|
{
|
|
if (controlId == -2)
|
|
{
|
|
playerdata->credits += mPrices[sel]; //We stole it.
|
|
GameApp::mycredits = playerdata->credits;
|
|
}
|
|
if (sel < BOOSTER_SLOTS) //Clicked a booster.
|
|
purchaseBooster(sel);
|
|
else
|
|
purchaseCard(sel);
|
|
|
|
//Check if we just scored an award...
|
|
if (myCollection && myCollection->totalPrice() > 10000)
|
|
{
|
|
GameOptionAward * goa = dynamic_cast<GameOptionAward *> (&options[Options::AWARD_COLLECTOR]);
|
|
if (goa) goa->giveAward();
|
|
}
|
|
}
|
|
mStage = STAGE_SHOP_SHOP;
|
|
return;
|
|
}
|
|
//Basic Menu.
|
|
switch (controlId)
|
|
{
|
|
case 12:
|
|
if (taskList)
|
|
taskList->save();
|
|
mStage = STAGE_SHOP_SHOP;
|
|
mParent->DoTransition(TRANSITION_FADE, GAME_STATE_MENU);
|
|
save();
|
|
GameStateMenu::genNbCardsStr();
|
|
break;
|
|
case 14:
|
|
mStage = STAGE_SHOP_TASKS;
|
|
if (!taskList)
|
|
taskList = NEW TaskList();
|
|
taskList->Start();
|
|
break;
|
|
case 15:
|
|
if (taskList)
|
|
taskList->End();
|
|
break;
|
|
case 22:
|
|
beginFilters();
|
|
break;
|
|
case -2:
|
|
{
|
|
playerdata->credits += 2000;
|
|
GameApp::mycredits = playerdata->credits;
|
|
}
|
|
default:
|
|
mStage = STAGE_SHOP_SHOP;
|
|
}
|
|
menu->Close();
|
|
}
|
|
|
|
void GameStateShop::OnScroll(int inXVelocity, int)
|
|
{
|
|
// we ignore magnitude since there isn't any scrolling in the shop
|
|
if (abs(inXVelocity) > 200)
|
|
{
|
|
bool flickRight = (inXVelocity >= 0);
|
|
if (flickRight)
|
|
mEngine->HoldKey_NoRepeat(JGE_BTN_PRI);
|
|
}
|
|
}
|
|
|
|
//ShopBooster
|
|
ShopBooster::ShopBooster()
|
|
{
|
|
pack = NULL;
|
|
mainSet = NULL;
|
|
altSet = NULL;
|
|
}
|
|
string ShopBooster::getSort()
|
|
{
|
|
if (pack)
|
|
return pack->getSort();
|
|
return "";
|
|
}
|
|
;
|
|
string ShopBooster::getName()
|
|
{
|
|
char buffer[512];
|
|
if (!mainSet && pack)
|
|
return pack->getName();
|
|
if (altSet == mainSet)
|
|
altSet = NULL;
|
|
if (altSet)
|
|
sprintf(buffer, _("%s & %s (15 Cards)").c_str(), mainSet->id.c_str(), altSet->id.c_str());
|
|
else if (mainSet)
|
|
sprintf(buffer, _("%s Booster (15 Cards)").c_str(), mainSet->id.c_str());
|
|
return buffer;
|
|
}
|
|
|
|
void ShopBooster::randomize(MTGPacks * packlist)
|
|
{
|
|
mainSet = NULL;
|
|
altSet = NULL;
|
|
pack = NULL;
|
|
if (!setlist.size())
|
|
return;
|
|
if (packlist && setlist.size() > 10)
|
|
{ //FIXME make these an unlockable item.
|
|
int rnd = rand() % 100;
|
|
if (rnd <= Constants::CHANCE_CUSTOM_PACK)
|
|
{
|
|
randomCustom(packlist);
|
|
return;
|
|
}
|
|
}
|
|
randomStandard();
|
|
}
|
|
int ShopBooster::basePrice()
|
|
{
|
|
if (pack)
|
|
return pack->getPrice();
|
|
else if (altSet)
|
|
return Constants::PRICE_MIXED_BOOSTER;
|
|
return Constants::PRICE_BOOSTER;
|
|
}
|
|
void ShopBooster::randomCustom(MTGPacks * packlist)
|
|
{
|
|
pack = packlist->randomPack();
|
|
if (pack && !pack->isUnlocked())
|
|
pack = NULL;
|
|
if (!pack)
|
|
randomStandard();
|
|
}
|
|
void ShopBooster::randomStandard()
|
|
{
|
|
|
|
MTGSetInfo * si = setlist.randomSet(-1);
|
|
mainSet = si;
|
|
altSet = NULL;
|
|
|
|
int mSetCount = si->counts[MTGSetInfo::TOTAL_CARDS];
|
|
if (mSetCount < 80)
|
|
{
|
|
if (rand() % 100 < Constants::CHANCE_PURE_OVERRIDE)
|
|
{ //Chance of picking a pure pack instead.
|
|
si = setlist.randomSet(-1, 80);
|
|
mSetCount = si->counts[MTGSetInfo::TOTAL_CARDS];
|
|
mainSet = si;
|
|
}
|
|
else
|
|
altSet = setlist.randomSet(si->block, 80 - mSetCount);
|
|
}
|
|
else if (rand() % 100 < Constants::CHANCE_MIXED_OVERRIDE) //Chance of having a mixed booster anyways.
|
|
altSet = setlist.randomSet(si->block);
|
|
|
|
for (int attempts = 0; attempts < 10; attempts++)
|
|
{ //Try to prevent altSet == mainSet.
|
|
if (altSet != mainSet)
|
|
break;
|
|
altSet = setlist.randomSet(-1, 80 - mSetCount);
|
|
}
|
|
if (altSet == mainSet)
|
|
altSet = NULL; //Prevent "10E & 10E Booster"
|
|
if (!altSet)
|
|
pack = mainSet->mPack;
|
|
|
|
}
|
|
int ShopBooster::maxInventory()
|
|
{
|
|
if (altSet || pack)
|
|
return 2;
|
|
return 5;
|
|
}
|
|
void ShopBooster::addToDeck(MTGDeck * d, WSrcCards *)
|
|
{
|
|
if (!pack)
|
|
{ //A combination booster.
|
|
MTGPack * mP = MTGPacks::getDefault();
|
|
if (!altSet && mainSet->mPack)
|
|
mP = mainSet->mPack;
|
|
char buf[512];
|
|
if (!altSet)
|
|
sprintf(buf, "set:%s;", mainSet->id.c_str());
|
|
else
|
|
sprintf(buf, "set:%s;|set:%s;", mainSet->id.c_str(), altSet->id.c_str());
|
|
mP->pool = buf;
|
|
mP->assemblePack(d); //Use the primary packfile. assemblePack deletes pool.
|
|
}
|
|
else
|
|
pack->assemblePack(d);
|
|
}
|
|
|
|
#ifdef TESTSUITE
|
|
bool ShopBooster::unitTest()
|
|
{
|
|
//this tests the default random pack creation.
|
|
MTGDeck * d = NEW MTGDeck(MTGCollection());
|
|
char result[1024];
|
|
|
|
randomStandard();
|
|
MTGPack * mP = MTGPacks::getDefault();
|
|
if(!altSet && mainSet->mPack) mP = mainSet->mPack;
|
|
char buf[512];
|
|
if(!altSet) sprintf(buf,"set:%s;",mainSet->id.c_str());
|
|
else sprintf(buf,"set:%s;|set:%s;",mainSet->id.c_str(),altSet->id.c_str());
|
|
mP->pool = buf;
|
|
mP->assemblePack(d); //Use the primary packfile. assemblePack deletes pool.
|
|
DeckDataWrapper* ddw = NEW DeckDataWrapper(d);
|
|
bool res = true;
|
|
|
|
int u = 0, r = 0, s = 0;
|
|
int card = 0;
|
|
for(int i=0;i<ddw->Size(true);i++)
|
|
{
|
|
MTGCard * c = ddw->getCard(i);
|
|
if(!c) break;
|
|
if(c->getRarity() == Constants::RARITY_R || c->getRarity() == Constants::RARITY_M)
|
|
r+=ddw->count(c);
|
|
else if(c->getRarity() == Constants::RARITY_U)
|
|
u+=ddw->count(c);
|
|
else if(c->getRarity() == Constants::RARITY_S)
|
|
s+=ddw->count(c);
|
|
card++;
|
|
}
|
|
int count = ddw->getCount();
|
|
SAFE_DELETE(ddw);
|
|
SAFE_DELETE(d);
|
|
//Note: When there are special cards, the count IS going to be messed up, so do not perform the check for Rare and Uncommon in that case
|
|
//also see http://code.google.com/p/wagic/issues/detail?id=644
|
|
if(!s && (r != 1 || u != 3) )
|
|
{
|
|
sprintf(result, "<span class=\"error\">==Unexpected rarity count==</span><br />");
|
|
TestSuite::Log(result);
|
|
res = false;
|
|
}
|
|
if(count < 14)
|
|
{
|
|
sprintf(result, "<span class=\"error\">==Unexpected card count==</span><br />");
|
|
TestSuite::Log(result);
|
|
res = false;
|
|
}
|
|
sprintf(result, "<span class=\"success\">==Test Successful !==</span><br />");
|
|
TestSuite::Log(result);
|
|
SAFE_DELETE(ddw);
|
|
SAFE_DELETE(d);
|
|
return res;
|
|
}
|
|
#endif
|