1053 lines
31 KiB
C++
1053 lines
31 KiB
C++
/*
|
|
The shop is where the player can buy cards, decks...
|
|
*/
|
|
#include "PrecompiledHeader.h"
|
|
|
|
#include <JRenderer.h>
|
|
#include "GameStateShop.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);
|
|
}
|
|
|
|
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)
|
|
return;
|
|
myCollection->Add(c);
|
|
int price = mPrices[controlId];
|
|
pricelist->setPrice(c->getMTGId(), price); // In case they changed their minds after cancelling.
|
|
playerdata->credits -= price;
|
|
//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];
|
|
mInventory[controlId]--;
|
|
SAFE_DELETE(booster);
|
|
deleteDisplay();
|
|
booster = NEW MTGDeck(MTGCollection());
|
|
boosterDisplay = NEW BoosterDisplay(12, NULL, SCREEN_WIDTH - 200, SCREEN_HEIGHT / 2, this, NULL, 5);
|
|
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 1,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;
|
|
|
|
JQuadPtr mBg = WResourceManager::Instance()->RetrieveTempQuad("shop.jpg", TEXTURE_SUB_5551);
|
|
if (mBg.get())
|
|
r->RenderQuad(mBg.get(), 0, 0);
|
|
|
|
JQuadPtr quad = WResourceManager::Instance()->RetrieveTempQuad("shop_light.jpg", TEXTURE_SUB_5551);
|
|
if (quad.get())
|
|
{
|
|
r->EnableTextureFilter(false);
|
|
r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE);
|
|
quad->SetColor(ARGB(lightAlpha,255,255,255));
|
|
r->RenderQuad(quad.get(), 0, 0);
|
|
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();
|
|
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));
|
|
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()))
|
|
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.
|
|
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();
|
|
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 += 1000;
|
|
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 Succesful !==</span><br />");
|
|
TestSuite::Log(result);
|
|
SAFE_DELETE(ddw);
|
|
SAFE_DELETE(d);
|
|
return res;
|
|
}
|
|
#endif
|