ULTIMA1: Further implementation of Grocery dialog

This commit is contained in:
Paul Gilbert 2020-01-19 21:33:21 -08:00 committed by Paul Gilbert
parent f16df23214
commit 3ed78dbfa8
12 changed files with 155 additions and 56 deletions

View File

@ -607,6 +607,7 @@ const char *const SRC_WHAT = " what?";
const char *const SRC_FACE_THE_LADDER = "Thou must face the ladder!";
const char *const SRC_CAUGHT = "Oh no! Thou wert caught!";
const char *const SRC_NONE_WILL_TALK = "None will talk to thee!";
const char *const SRC_NOT_BY_COUNTER = "Thou art not by a counter!";
const char *const SRC_GROCERY_NAMES[8] = {
"Li'l Karelia's Finnish Grocery", "Adventurer's Supply Post", "", "The Brown Bag", "Fresh Food Marketplace",
@ -657,10 +658,10 @@ const char *const SRC_LADDER_CREATED = "Ladder created!";
const char *const SRC_QUEST_COMPLETED = "A quest has been completed!";
const char *const SRC_GROCERY_SELL = "Used food? No thanks!";
const char *const SRC_GROCERY_PACKS1 = "Packs of 10 food cost %d pence";
const char *const SRC_GROCERY_PACKS1 = "Packs of 10 food cost %u pence";
const char *const SRC_GROCERY_PACKS2 = "each. How many dost thou";
const char *const SRC_GROCERY_PACKS3 = "wish to purchase?";
const char *const SRC_GROCERY_PACKS_FOOD = "%d packs food";
const char *const SRC_GROCERY_PACKS_FOOD = "%u packs food";
const char *const SRC_GROCERY_FIND_PACKS = "Thou dost find %d bags of food!";
const char *const SRC_WITH_KING = " with king";
@ -748,6 +749,7 @@ GameResources::GameResources(Shared::Resources *resManager) : LocalResourceFile(
FACE_THE_LADDER = SRC_FACE_THE_LADDER;
CAUGHT = SRC_CAUGHT;
NONE_WILL_TALK = SRC_NONE_WILL_TALK;
NOT_BY_COUNTER = SRC_NOT_BY_COUNTER;
BUY_SELL = SRC_BUY_SELL;
BUY = SRC_BUY;
SELL = SRC_SELL;
@ -875,6 +877,7 @@ void GameResources::synchronize() {
syncString(FACE_THE_LADDER);
syncString(CAUGHT);
syncString(NONE_WILL_TALK);
syncString(NOT_BY_COUNTER);
syncString(BUY_SELL);
syncString(BUY);
syncString(SELL);

View File

@ -105,6 +105,7 @@ public:
const char *FACE_THE_LADDER;
const char *CAUGHT;
const char *NONE_WILL_TALK;
const char *NOT_BY_COUNTER;
const char *BUY_SELL;
const char *BUY;
const char *SELL;

View File

@ -337,10 +337,17 @@ void MapCity::get() {
void MapCity::talk() {
if (_guardsHostile) {
addInfoMsg(_game->_res->NONE_WILL_TALK);
}
} else {
Widgets::Person *person = getTalkPerson();
// TODO
if (person) {
person->talk();
} else {
addInfoMsg("");
addInfoMsg(_game->_res->NOT_BY_COUNTER);
_game->endOfTurn();
}
}
}
void MapCity::unlock() {

View File

@ -31,6 +31,7 @@ namespace Ultima1 {
namespace U1Dialogs {
BEGIN_MESSAGE_MAP(BuySellDialog, Dialog)
ON_MESSAGE(ShowMsg)
ON_MESSAGE(CharacterInputMsg)
END_MESSAGE_MAP()
@ -39,6 +40,34 @@ BuySellDialog::BuySellDialog(Ultima1Game *game, const Common::String &title) :
_bounds = Rect(31, 23, 287, 127);
}
bool BuySellDialog::ShowMsg(CShowMsg &msg) {
addInfoMsg(_game->_res->BUY_SELL, false);
getKeypress();
return true;
}
bool BuySellDialog::CharacterInputMsg(CCharacterInputMsg &msg) {
switch (_mode) {
case SELECT:
if (msg._keyState.keycode == Common::KEYCODE_b)
setMode(BUY);
else if (msg._keyState.keycode == Common::KEYCODE_s)
setMode(SELL);
else
nothing();
break;
case CANT_AFFORD:
addInfoMsg("", true, true);
break;
default:
break;
}
return true;
}
void BuySellDialog::draw() {
Dialog::draw();
Shared::Gfx::VisualSurface s = getSurface();
@ -52,28 +81,7 @@ void BuySellDialog::draw() {
s.writeString(_title, Point((_bounds.width() - _title.size() * 8) / 2, 9));
}
// Clear part of the bottom info text line
s.fillRect(TextRect(8, 24, 28, 24), _game->_bgColor);
switch (_mode) {
case SELECT: {
// Display the buy/sell text and prompt for input
s.writeString(_game->_res->BUY_SELL, TextPoint(8, 24));
_charInput.show(TextPoint(20, 24), _game->_textColor, this);
break;
}
case BUY: {
// Display the buy/sell text and prompt for input
s.writeString(_game->_res->BUY, TextPoint(8, 24));
_charInput.show(TextPoint(15, 24), _game->_textColor, this);
break;
}
case SELL: {
// Display the buy/sell text and prompt for input
s.writeString(_game->_res->SELL, TextPoint(8, 24));
_charInput.show(TextPoint(15, 24), _game->_textColor, this);
break;
}
case SOLD:
s.writeString(getGame()->_res->SOLD, TextPoint(14, 5));
break;
@ -90,28 +98,33 @@ void BuySellDialog::draw() {
void BuySellDialog::setMode(BuySell mode) {
_mode = mode;
setDirty();
}
bool BuySellDialog::CharacterInputMsg(CCharacterInputMsg &msg) {
switch (_mode) {
case SELECT:
if (msg._keyState.keycode == Common::KEYCODE_b)
setMode(BUY);
else if (msg._keyState.keycode == Common::KEYCODE_s)
setMode(SELL);
else
nothing();
case BUY:
addInfoMsg(Common::String::format("%s%s", _game->_res->ACTION_NAMES[19], _game->_res->BUY), false, true);
getKeypress();
break;
case SELL:
addInfoMsg(Common::String::format("%s%s", _game->_res->ACTION_NAMES[19], _game->_res->SELL), false, true);
getKeypress();
break;
case CANT_AFFORD:
addInfoMsg(_game->_res->NOTHING);
addInfoMsg(_game->_res->PRESS_SPACE_TO_CONTINUE, false);
_game->playFX(1);
getKeypress();
break;
default:
break;
}
return true;
}
void BuySellDialog::nothing() {
addInfoMsg(Common::String::format(" %s", _game->_res->NOTHING));
addInfoMsg(_game->_res->NOTHING);
_game->endOfTurn();
hide();
}

View File

@ -32,6 +32,7 @@ namespace U1Dialogs {
enum BuySell { SELECT, BUY, SELL, SOLD, CANT_AFFORD };
using Shared::CShowMsg;
using Shared::CCharacterInputMsg;
/**
@ -39,6 +40,7 @@ using Shared::CCharacterInputMsg;
*/
class BuySellDialog : public Dialog {
DECLARE_MESSAGE_MAP;
bool ShowMsg(CShowMsg &msg);
virtual bool CharacterInputMsg(CCharacterInputMsg &msg);
private:
Shared::Gfx::CharacterInput _charInput;
@ -59,7 +61,7 @@ protected:
/**
* Set the mode
*/
void setMode(BuySell mode);
virtual void setMode(BuySell mode);
/**
* Switches the dialog to displaying sold

View File

@ -63,6 +63,11 @@ void Dialog::draw() {
infoArea->draw();
}
void Dialog::centerText(const Common::String &line, int yp) {
Shared::Gfx::VisualSurface s = getSurface();
s.writeString(line, TextPoint((_bounds.width() / 8 - line.size() + 1) / 2, yp));
}
void Dialog::hide() {
Popup::hide();

View File

@ -71,6 +71,11 @@ protected:
* Prompts for an input
*/
void getInput(bool isNumeric = true, size_t maxCharacters = 4);
/**
* Write a text line to the dialog
*/
void centerText(const Common::String &line, int yp);
public:
/**
* Constructor

View File

@ -190,6 +190,8 @@ void Drop::draw() {
case DROP_ARMOR:
drawDropArmor();
break;
default:
break;
}
}

View File

@ -21,21 +21,49 @@
*/
#include "ultima/ultima1/u1dialogs/grocery.h"
#include "ultima/ultima1/game.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/engine/messages.h"
namespace Ultima {
namespace Ultima1 {
namespace U1Dialogs {
EMPTY_MESSAGE_MAP(Grocery, BuySellDialog);
BEGIN_MESSAGE_MAP(Grocery, BuySellDialog)
ON_MESSAGE(TextInputMsg)
ON_MESSAGE(FrameMsg)
END_MESSAGE_MAP()
Grocery::Grocery(Ultima1Game *game, int groceryNum) : BuySellDialog(game, game->_res->GROCERY_NAMES[groceryNum]) {
Grocery::Grocery(Ultima1Game *game, int groceryNum) : BuySellDialog(game, game->_res->GROCERY_NAMES[groceryNum - 1]),
_frameCounter(0) {
Shared::Character &c = *game->_party;
_costPerPack = 5 - c._intelligence / 20;
}
void Grocery::setMode(BuySell mode) {
switch (mode) {
case BUY:
addInfoMsg(Common::String::format("%s%s", _game->_res->ACTION_NAMES[19], _game->_res->BUY), false, true);
_mode = BUY;
setDirty();
getInput(true, 3);
break;
case SELL:
addInfoMsg(Common::String::format("%s%s", _game->_res->ACTION_NAMES[19], _game->_res->SELL), false, true);
_mode = SELL;
_frameCounter = 1;
setDirty();
break;
default:
BuySellDialog::setMode(mode);
break;
}
}
void Grocery::draw() {
BuySellDialog::draw();
Shared::Gfx::VisualSurface s = getSurface();
@ -43,13 +71,13 @@ void Grocery::draw() {
switch (_mode) {
case BUY:
s.writeString(game->_res->GROCERY_PACKS1, TextPoint(5, 8));
s.writeString(game->_res->GROCERY_PACKS2, TextPoint(8, 9));
s.writeString(game->_res->GROCERY_PACKS3, TextPoint(15, 10));
centerText(Common::String::format(game->_res->GROCERY_PACKS1, _costPerPack), 4);
centerText(game->_res->GROCERY_PACKS2, 5);
centerText(game->_res->GROCERY_PACKS3, 6);
break;
case SELL:
s.writeString(game->_res->GROCERY_SELL, TextPoint(9, 8));
centerText(game->_res->GROCERY_SELL, 4);
break;
default:
@ -57,6 +85,38 @@ void Grocery::draw() {
}
}
bool Grocery::TextInputMsg(CTextInputMsg &msg) {
assert(_mode == BUY);
Shared::Character &c = *_game->_party;
uint amount = atoi(msg._text.c_str());
uint cost = amount * _costPerPack;
if (msg._escaped || !amount) {
nothing();
} else if (cost > c._coins) {
cantAfford();
} else {
addInfoMsg(msg._text);
c._coins -= cost;
c._food += amount * 10;
addInfoMsg(Common::String::format(_game->_res->GROCERY_PACKS_FOOD, amount));
_game->endOfTurn();
hide();
}
return true;
}
bool Grocery::FrameMsg(CFrameMsg &msg) {
if (_frameCounter > 0 && ++_frameCounter > 50) {
_game->endOfTurn();
hide();
}
return true;
}
} // End of namespace U1Dialogs
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@ -29,13 +29,24 @@ namespace Ultima {
namespace Ultima1 {
namespace U1Dialogs {
using Shared::CFrameMsg;
using Shared::CTextInputMsg;
/**
* Implements the buy/sell dialog for grocers
*/
class Grocery : public BuySellDialog {
DECLARE_MESSAGE_MAP;
bool FrameMsg(CFrameMsg &msg);
bool TextInputMsg(CTextInputMsg &msg);
private:
uint _costPerPack;
uint _frameCounter;
protected:
/**
* Set the mode
*/
virtual void setMode(BuySell mode) override;
public:
CLASSDEF;

View File

@ -109,11 +109,6 @@ void King::draw() {
centerText(_game->_res->KING_TEXT[11], 7);
}
void King::centerText(const Common::String &line, int yp) {
Shared::Gfx::VisualSurface s = getSurface();
s.writeString(line, TextPoint(16 - line.size() / 2, yp));
}
void King::setMode(KingMode mode) {
_mode = mode;

View File

@ -76,11 +76,6 @@ private:
* Give hit points
*/
void giveHitPoints(uint amount);
/**
* Write a text line to the dialog
*/
void centerText(const Common::String &line, int yp);
public:
CLASSDEF;