1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "ultima/ultima1/u1dialogs/drop.h"
24 #include "ultima/ultima1/game.h"
25 #include "ultima/ultima1/core/resources.h"
26 #include "ultima/ultima1/maps/map.h"
27 #include "ultima/shared/engine/messages.h"
28 
29 namespace Ultima {
30 namespace Ultima1 {
31 namespace U1Dialogs {
32 
BEGIN_MESSAGE_MAP(Drop,Dialog)33 BEGIN_MESSAGE_MAP(Drop, Dialog)
34 	ON_MESSAGE(ShowMsg)
35 	ON_MESSAGE(CharacterInputMsg)
36 	ON_MESSAGE(TextInputMsg)
37 END_MESSAGE_MAP()
38 
39 Drop::Drop(Ultima1Game *game) : FullScreenDialog(game), _mode(SELECT) {
40 }
41 
ShowMsg(CShowMsg * msg)42 bool Drop::ShowMsg(CShowMsg *msg) {
43 	addInfoMsg(_game->_res->DROP_PENCE_WEAPON_armour, false);
44 	getKeypress();
45 	return true;
46 }
47 
CharacterInputMsg(CCharacterInputMsg * msg)48 bool Drop::CharacterInputMsg(CCharacterInputMsg *msg) {
49 	Shared::Character &c = *_game->_party;
50 
51 	switch (_mode) {
52 	case SELECT:
53 		switch (msg->_keyState.keycode) {
54 		case Common::KEYCODE_p:
55 			setMode(DROP_PENCE);
56 			break;
57 		case Common::KEYCODE_w:
58 			setMode(DROP_WEAPON);
59 			break;
60 		case Common::KEYCODE_a:
61 			setMode(DROP_armour);
62 			break;
63 		default:
64 			nothing();
65 			break;
66 		}
67 		break;
68 
69 	case DROP_WEAPON:
70 		if (msg->_keyState.keycode >= Common::KEYCODE_b && msg->_keyState.keycode < (Common::KEYCODE_b + (int)c._weapons.size())
71 			&& !c._weapons[msg->_keyState.keycode - Common::KEYCODE_a]->empty()) {
72 			// Drop the weapon
73 			int weaponNum = msg->_keyState.keycode - Common::KEYCODE_a;
74 			if (c._weapons[weaponNum]->decrQuantity() && c._equippedWeapon == weaponNum)
75 				c.removeWeapon();
76 
77 			addInfoMsg(Common::String::format("%s%s", _game->_res->DROP_WEAPON,
78 				_game->_res->WEAPON_NAMES_UPPERCASE[weaponNum]), true, true);
79 			hide();
80 		} else {
81 			none();
82 		}
83 		break;
84 
85 	case DROP_armour:
86 		if (msg->_keyState.keycode >= Common::KEYCODE_b && msg->_keyState.keycode < (Common::KEYCODE_b + (int)c._armour.size())
87 			&& c._armour[msg->_keyState.keycode - Common::KEYCODE_a]->_quantity > 0) {
88 			// Drop the armor
89 			int armorNum = msg->_keyState.keycode - Common::KEYCODE_a;
90 			if (c._armour[armorNum]->decrQuantity() && c._equippedArmour == armorNum)
91 				c.removeArmour();
92 
93 			addInfoMsg(Common::String::format("%s%s", _game->_res->DROP_armour,
94 				_game->_res->ARMOR_NAMES[armorNum]), true, true);
95 			hide();
96 		} else {
97 			none();
98 		}
99 		break;
100 
101 	default:
102 		break;
103 	}
104 
105 	return true;
106 }
107 
TextInputMsg(CTextInputMsg * msg)108 bool Drop::TextInputMsg(CTextInputMsg *msg) {
109 	Shared::Character &c = *_game->_party;
110 	assert(_mode == DROP_PENCE);
111 	Ultima1Game *game = _game;
112 	Maps::Ultima1Map *map = getMap();
113 
114 	uint amount = atoi(msg->_text.c_str());
115 
116 	if (msg->_escaped || !amount) {
117 		none();
118 
119 	} else {
120 		addInfoMsg(Common::String::format(" %u", amount));
121 
122 		if (amount > c._coins) {
123 			addInfoMsg(game->_res->NOT_THAT_MUCH);
124 			game->playFX(1);
125 		} else {
126 			c._coins -= amount;
127 			hide();
128 
129 			map->dropCoins(amount);
130 		}
131 	}
132 
133 	return true;
134 }
135 
setMode(Mode mode)136 void Drop::setMode(Mode mode) {
137 	setDirty();
138 	_mode = mode;
139 
140 	const Shared::Character &c = *_game->_party;
141 	switch (mode) {
142 	case DROP_PENCE:
143 		addInfoMsg(_game->_res->DROP_PENCE, false, true);
144 		getInput();
145 		break;
146 
147 	case DROP_WEAPON:
148 		if (c._weapons.hasNothing()) {
149 			nothing();
150 		} else {
151 			addInfoMsg(_game->_res->DROP_WEAPON, false, true);
152 			getKeypress();
153 		}
154 		break;
155 
156 	case DROP_armour:
157 		if (c._armour.hasNothing()) {
158 			nothing();
159 		} else {
160 			addInfoMsg(_game->_res->DROP_armour, false, true);
161 			getKeypress();
162 		}
163 		break;
164 
165 	default:
166 		break;
167 	}
168 }
169 
nothing()170 void Drop::nothing() {
171 	addInfoMsg(Common::String::format("%s %s", _game->_res->ACTION_NAMES[3],
172 		_game->_res->NOTHING), true, true);
173 	hide();
174 }
175 
none()176 void Drop::none() {
177 	const char *DROPS[4] = { nullptr, _game->_res->DROP_PENCE, _game->_res->DROP_WEAPON, _game->_res->DROP_armour };
178 
179 	addInfoMsg(Common::String::format("%s%s", DROPS[_mode], _game->_res->NONE), true, true);
180 	hide();
181 }
182 
draw()183 void Drop::draw() {
184 	Dialog::draw();
185 
186 	switch (_mode) {
187 	case DROP_WEAPON:
188 		drawDropWeapon();
189 		break;
190 	case DROP_armour:
191 		drawDropArmor();
192 		break;
193 	default:
194 		break;
195 	}
196 }
197 
drawDropWeapon()198 void Drop::drawDropWeapon() {
199 	Shared::Gfx::VisualSurface s = getSurface();
200 	drawFrame(_game->_res->ACTION_NAMES[3]);
201 
202 	// Count the number of different types of weapons
203 	const Shared::Character &c = *_game->_party;
204 	int numLines = 0;
205 	for (uint idx = 1; idx < c._weapons.size(); ++idx) {
206 		if (c._weapons[idx]->_quantity)
207 			++numLines;
208 	}
209 
210 	// Draw lines for weapons the player has
211 	int yp = 10 - (numLines / 2);
212 	for (uint idx = 1; idx < c._weapons.size(); ++idx) {
213 		if (c._weapons[idx]->_quantity) {
214 			Common::String text = Common::String::format("%c) %s", 'a' + idx,
215 				_game->_res->WEAPON_NAMES_UPPERCASE[idx]);
216 			s.writeString(text, TextPoint(15, yp++));
217 		}
218 	}
219 }
220 
drawDropArmor()221 void Drop::drawDropArmor() {
222 	Shared::Gfx::VisualSurface s = getSurface();
223 	drawFrame(_game->_res->ACTION_NAMES[3]);
224 
225 	// Count the number of different types of armor
226 	const Shared::Character &c = *_game->_party;
227 	int numLines = 0;
228 	for (uint idx = 1; idx < c._armour.size(); ++idx) {
229 		if (c._armour[idx]->_quantity)
230 			++numLines;
231 	}
232 
233 	// Draw lines for armor the player has
234 	int yp = 10 - (numLines / 2);
235 	for (uint idx = 1; idx < c._armour.size(); ++idx) {
236 		if (c._armour[idx]->_quantity) {
237 			Common::String text = Common::String::format("%c) %s", 'a' + idx,
238 				_game->_res->ARMOR_NAMES[idx]);
239 			s.writeString(text, TextPoint(13, yp++));
240 		}
241 	}
242 }
243 
244 } // End of namespace U1Dialogs
245 } // End of namespace Ultima1
246 } // End of namespace Ultima
247