World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
UIGuilds.cpp
См. документацию.
1 #include "GUI/UI/UIGuilds.h"
2 
3 #include "Engine/Engine.h"
4 #include "Engine/Events2D.h"
5 #include "Engine/LOD.h"
6 #include "Engine/Localization.h"
7 #include "Engine/Party.h"
8 
9 #include "Engine/Objects/Items.h"
10 
12 #include "Engine/Graphics/Image.h"
13 
14 #include "GUI/GUIWindow.h"
15 #include "GUI/GUIButton.h"
16 #include "GUI/GUIFont.h"
17 #include "GUI/UI/UIHouses.h"
18 #include "GUI/UI/UIShops.h"
19 #include "GUI/UI/UIStatusBar.h"
20 
21 #include "IO/Mouse.h"
22 
24 
26 
27 void GuildDialog() {
28  int textoffset; // ecx@47
29  GUIButton *pButton; // eax@49
30  int pTextHeight; // eax@55
31  unsigned __int16 pTextColor; // ax@55
32  int textspacings; // [sp+2D4h] [bp-18h]@1
33  bool pSkillFlag; // [sp+2DCh] [bp-10h]@35
34  int dialogopts; // [sp+2E0h] [bp-Ch]@35
35 
36  int all_text_height;
37  int pX;
38 
39  GUIWindow working_window = *window_SpeakInHouse;
40  working_window.uFrameX = 483;
41  working_window.uFrameWidth = 148;
42  working_window.uFrameZ = 334;
43 
44  int base_teach_price =
45  (p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1]
47  500.0);
48  int pPrice = base_teach_price *
49  (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
50  if (pPrice < base_teach_price / 3) pPrice = base_teach_price / 3;
51 
52  if (dialog_menu_id == HOUSE_DIALOGUE_MAIN) { // change to switch??
54  (uint8_t *)pPlayers[uActiveCharacter]->_achieved_awards_bits,
55  guild_mambership_flags[(unsigned int)
57  139])) { // you must me member
58  pTextHeight = pFontArrus->CalcTextHeight(
59  pNPCTopics[121].pText, working_window.uFrameWidth, 0);
60  working_window.DrawTitleText(
61  pFontArrus, 0, (212 - pTextHeight) / 2 + 101,
62  Color16(0xFFu, 0xFFu, 0x9Bu), pNPCTopics[121].pText, 3);
64  return;
65  }
66 
68  return;
69  }
70 
71  dialogopts = 0;
72  pSkillFlag = false;
73  all_text_height = 0;
75  i < pDialogueWindow->pNumPresenceButton +
77  ++i) {
78  if (pDialogueWindow->GetControl(i)->msg_param == 18) {
79  all_text_height += pFontArrus->CalcTextHeight(
80  localization->GetString(400), working_window.uFrameWidth,
81  0); // "Buy Spells"
82  dialogopts++;
83  } else {
85  [pPlayers[uActiveCharacter]->classType]
86  [pDialogueWindow->GetControl(i)->msg_param - 36] &&
87  !pPlayers[uActiveCharacter]->pActiveSkills
88  [pDialogueWindow->GetControl(i)->msg_param - 36]) {
89  all_text_height += pFontArrus->CalcTextHeight(
92  working_window.uFrameWidth, 0, 0);
93  dialogopts++;
94  pSkillFlag = true;
95  }
96  }
97  }
98 
99  if (!dialogopts) { // code never gets here??
101  544, pPlayers[uActiveCharacter]->pName,
103  pPlayers[uActiveCharacter]->classType)) +
104  "\n \n" // Seek knowledge elsewhere %s the %s
106  528); // "I can offer you nothing further."
107  pTextHeight =
108  pFontArrus->CalcTextHeight(str, working_window.uFrameWidth, 0);
109  working_window.DrawTitleText(pFontArrus, 0,
110  (174 - pTextHeight) / 2 + 138,
111  Color16(0xFFu, 0xFFu, 0x9Bu), str, 3);
112  return;
113  }
114 
115  if (pSkillFlag) {
116  working_window.DrawTitleText(
117  pFontArrus, 0, 0x92u, 0,
118  localization->FormatString(401, pPrice), 3); // Skill Cost: %lu
119  }
120 
121  textspacings = (149 - all_text_height) / dialogopts;
122  if (textspacings > 32) {
123  textspacings = 32;
124  }
125 
126  textoffset = 162 - textspacings / 2;
127 
129  i < pDialogueWindow->pNumPresenceButton +
131  ++i) {
132  pButton = pDialogueWindow->GetControl(i);
133 
134  if (pButton->msg_param == 18) {
135  pButton->uY = textspacings + textoffset;
136  pTextHeight =
138  working_window.uFrameWidth, 0);
139  pButton->uHeight = pTextHeight;
140  textoffset = pButton->uY + pTextHeight - 1;
141  pButton->uW = textoffset + 6;
142  pTextColor = Color16(0xFFu, 0xFFu, 0x9Bu);
144  pTextColor = Color16(0xFFu, 0xFFu, 0xFFu);
145  }
146  working_window.DrawTitleText(
147  pFontArrus, 0, pButton->uY, pTextColor,
148  localization->GetString(400), 3); // "Buy Spells"
149  } else {
151  [pPlayers[uActiveCharacter]->classType]
152  [pButton->msg_param - 36] &&
154  ->pActiveSkills[pButton->msg_param - 36]) {
155  pButton->uY = textspacings + textoffset;
156  pTextHeight = pFontArrus->CalcTextHeight(
157  localization->GetSkillName(pButton->msg_param - 36),
158  working_window.uFrameWidth, 0);
159  pButton->uHeight = pTextHeight;
160  textoffset = pButton->uY + pTextHeight - 1;
161  pButton->uW = textoffset + 6;
162  pTextColor = Color16(0xFFu, 0xFFu, 0x9Bu);
164  pTextColor = Color16(0xFFu, 0xFFu, 0xFFu);
165  }
166  working_window.DrawTitleText(
167  pFontArrus, 0, pButton->uY, pTextColor,
168  localization->GetSkillName(pButton->msg_param - 36), 3);
169  } else {
170  pButton->uW = 0;
171  pButton->uHeight = 0;
172  pButton->uY = 0;
173  }
174  }
175  }
176  return;
177  }
178 
179  if (dialog_menu_id == HOUSE_DIALOGUE_GUILD_BUY_BOOKS) { // buy books
180  render->DrawTextureAlphaNew(8 / 640.0f, 8 / 480.0f, shop_ui_background);
181  int itemxind = 0;
182 
183  for (pX = 32; pX < 452; pX += 70) { //расположение в верхнем ряду
184  if (pParty
185  ->SpellBooksInGuilds[window_SpeakInHouse->par1C - 139]
186  [itemxind]
187  .uItemID) {
188  render->DrawTextureAlphaNew(
189  pX / 640.0f, 90 / 480.0f,
190  shop_ui_items_in_store[itemxind]); // top row
191  }
192  if (pParty
193  ->SpellBooksInGuilds[window_SpeakInHouse->par1C - 139]
194  [itemxind + 6]
195  .uItemID) {
196  render->DrawTextureAlphaNew(
197  pX / 640.0f, 250 / 480.0f,
198  shop_ui_items_in_store[itemxind + 6]);
199  }
200 
201  ++itemxind;
202  }
203 
205  int itemcount = 0;
206  for (uint i = 0; i < 12; ++i) {
207  if (pParty
208  ->SpellBooksInGuilds[window_SpeakInHouse->par1C - 139]
209  [i]
210  .uItemID > 0)
211  ++itemcount;
212  }
213 
215  0); // "Select the Item to Buy"
216 
217  if (!itemcount) { // shop empty
221  139] -
223  return;
224  }
225 
227  int testx = (pt.x - 32) / 70;
228  if (testx >= 0 && testx < 6) {
229  if (pt.y >= 250) {
230  testx += 6;
231  }
232 
233  ItemGen *item = &pParty->SpellBooksInGuilds[window_SpeakInHouse->par1C - 139][testx];
234 
235  if (item->uItemID) {
236  int testpos;
237  if (pt.y >= 250) {
238  testpos = 32 + 70 * testx - 420;
239  } else {
240  testpos = 32 + 70 * testx;
241  }
242 
243  if (pt.x >= testpos &&
244  pt.x <=
245  testpos +
246  shop_ui_items_in_store[testx]->GetWidth()) {
247  if ((pt.y >= 90 &&
248  pt.y <= (90 + shop_ui_items_in_store[testx]
249  ->GetHeight())) ||
250  (pt.y >= 250 &&
251  pt.y <= (250 + shop_ui_items_in_store[testx]
252  ->GetHeight()))) {
253  auto str = BuildDialogueString(
256  ->SelectPhrasesTransaction(
259  2)],
260  uActiveCharacter - 1, item,
261  (char *)window_SpeakInHouse->ptr_1C, 2);
262  pTextHeight = pFontArrus->CalcTextHeight(
263  str, working_window.uFrameWidth, 0);
264  working_window.DrawTitleText(
265  pFontArrus, 0, (174 - pTextHeight) / 2 + 138,
266  Color16(0xFFu, 0xFFu, 0xFFu), str, 3);
267  return;
268  }
269  }
270  }
271  }
272  }
273  return;
274  }
275 
276  if (HouseUI_CheckIfPlayerCanInteract()) { // buy skills
277  if (pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id - 36]) {
279  403,
280  localization->GetSkillName(dialog_menu_id - 36))); // You already know the %s skill
281  pAudioPlayer->PlaySound(SOUND_error, 0, 0, -1, 0, 0);
282  } else {
283  if (pParty->GetGold() < pPrice) {
284  GameUI_StatusBar_OnEvent(localization->GetString(LSTR_NOT_ENOUGH_GOLD));
287  } else {
288  Party::TakeGold(pPrice);
289  pPlayers[uActiveCharacter]->pActiveSkills[dialog_menu_id - 36] =
290  1;
291  }
292  }
293  }
294  pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
295 }
296 
297 //----- (004BC8D5) --------------------------------------------------------
298 void SpellBookGenerator() { // for GuildDialogs
299  int pItemNum; // esi@1
300  int randomnum; // esi@7
301 
302  for (int i = 0; i < 12; ++i) {
303  if (p2DEvents[window_SpeakInHouse->par1C - 1].uType >= 5) {
304  if (p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 13) {
305  pItemNum =
306  rand() %
307  word_4F0F30[(signed int)window_SpeakInHouse->par1C -
308  139] +
309  11 *
310  p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1]
311  .uType +
312  345;
313  } else {
314  if (p2DEvents[window_SpeakInHouse->par1C - 1].uType == 14)
315  randomnum = rand() % 4;
316  else if (p2DEvents[window_SpeakInHouse->par1C - 1].uType == 15)
317  randomnum = rand() % 3 + 4;
318  else if (p2DEvents[window_SpeakInHouse->par1C - 1].uType == 16)
319  randomnum = rand() % 2 + 7;
320  if (p2DEvents[window_SpeakInHouse->par1C - 1].uType <= 16)
321  pItemNum =
322  rand() %
323  word_4F0F30[(signed int)window_SpeakInHouse->par1C -
324  139] +
325  11 * randomnum + 400;
326  }
327  }
328 
329  if (pItemNum == 487) { // divine intervention check
330  if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 239))
331  pItemNum = 486;
332  }
333 
334  ItemGen *item_spellbook =
336  item_spellbook->Reset();
338  .uItemID = pItemNum;
340  .IsIdentified();
341 
343  pItemsTable->pItems[pItemNum].pIconName, 0x7FF);
344  }
345 }
uint16_t
unsigned __int16 uint16_t
Definition: SDL_config.h:37
Engine_::IocContainer
Definition: IocContainer.h:15
Localization::GetString
const char * GetString(unsigned int index) const
Definition: Localization.cpp:13
UIMSG_Escape
@ UIMSG_Escape
Definition: GUIWindow.h:96
_2devent::uType
BuildingType uType
Definition: Events2D.h:41
LOD.h
Party::GetPlayingTime
GameTime & GetPlayingTime()
Definition: Party.h:230
Mouse::GetCursorPos
Point GetCursorPos()
Definition: Mouse.cpp:108
GUIWindow
Definition: GUIWindow.h:433
Items.h
GuildDialog
void GuildDialog()
Definition: UIGuilds.cpp:27
shop_ui_background
Image * shop_ui_background
Definition: UIShops.cpp:33
_449B57_test_bit
bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2)
Definition: Party.cpp:1185
PartyTimeStruct::Shops_next_generation_time
std::array< GameTime, 85 > Shops_next_generation_time
Definition: Party.h:143
dialog_menu_id
HOUSE_DIALOGUE_MENU dialog_menu_id
Definition: UIHouses.cpp:50
pNPCTopics
std::array< NPCTopic, 789 > pNPCTopics
Definition: mm7_data.cpp:740
AudioPlayer::PlaySound
void PlaySound(SoundID eSoundID, int pid, unsigned int uNumRepeats, int x, int y, int a7)
Definition: AudioPlayer.cpp:195
SOUND_error
@ SOUND_error
Definition: AudioPlayer.h:19
Party::_quest_bits
unsigned __int8 _quest_bits[64]
Definition: Party.h:291
localization
Localization * localization
Definition: Localization.cpp:11
SpellBookGenerator
void SpellBookGenerator()
Definition: UIGuilds.cpp:298
Point::x
unsigned int x
Definition: Point.h:7
GameUI_StatusBar_DrawImmediate
void GameUI_StatusBar_DrawImmediate(const String &str, int color)
Definition: UIStatusBar.cpp:88
GUIWindow::DrawTitleText
void DrawTitleText(GUIFont *font, int horizontal_margin, int vertical_margin, unsigned __int16 uDefaultColor, const char *pInString, int line_spacing)
Definition: GUIWindow.cpp:665
GUIFont.h
ItemGen::Reset
void Reset()
Definition: Items.cpp:133
pPlayers
NZIArray< struct Player *, 5 > pPlayers
Definition: Player.cpp:46
GUIWindow::uFrameWidth
unsigned int uFrameWidth
Definition: GUIWindow.h:470
Localization::GetSkillName
const char * GetSkillName(unsigned int index) const
Definition: Localization.h:51
GUIButton
Definition: GUIButton.h:11
GUIWindow::uFrameZ
unsigned int uFrameZ
Definition: GUIWindow.h:472
Engine.h
Party::PartyTimes
PartyTimeStruct PartyTimes
Definition: Party.h:249
Image.h
p2DEvents
_2devent p2DEvents[525]
Definition: Events.cpp:57
GUIWindow::pStartingPosActiveItem
int pStartingPosActiveItem
Definition: GUIWindow.h:485
UIHouses.h
pItemsTable
struct ItemsTable * pItemsTable
Definition: Items.cpp:37
Localization.h
window_SpeakInHouse
GUIWindow * window_SpeakInHouse
Definition: GUIWindow.cpp:51
GUIButton.h
pParty
Party * pParty
Definition: Party.cpp:30
HOUSE_DIALOGUE_MAIN
@ HOUSE_DIALOGUE_MAIN
Definition: UIHouses.h:8
word_4F0F30
std::array< int16_t, 32 > word_4F0F30
Definition: mm7_data.cpp:496
pFontArrus
GUIFont * pFontArrus
Definition: GUIFont.cpp:18
GUIWindow::pCurrentPosActiveItem
int pCurrentPosActiveItem
Definition: GUIWindow.h:482
IRender.h
HOUSE_DIALOGUE_GUILD_BUY_BOOKS
@ HOUSE_DIALOGUE_GUILD_BUY_BOOKS
Definition: UIHouses.h:25
GUIWindow::pNumPresenceButton
int pNumPresenceButton
Definition: GUIWindow.h:481
ItemGen::uItemID
int uItemID
Definition: Items.h:326
AssetsManager::GetImage_ColorKey
Texture * GetImage_ColorKey(const String &name, uint16_t colorkey)
Definition: AssetsManager.cpp:34
UIGuilds.h
Engine_::IocContainer::ResolveMouse
static Mouse * ResolveMouse()
Definition: IocContainer.cpp:88
Party::TakeGold
static void TakeGold(int amount)
Definition: Party.cpp:292
GUIFont::CalcTextHeight
unsigned int CalcTextHeight(const String &str, unsigned int width, int x_offset, bool return_on_carriage=false)
Definition: GUIFont.cpp:246
BuildingType_MagicShop
@ BuildingType_MagicShop
Definition: Events2D.h:7
Party.h
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
shop_ui_items_in_store
std::array< Image *, 12 > shop_ui_items_in_store
Definition: UIShops.cpp:35
Events2D.h
PlayHouseSound
void PlayHouseSound(unsigned int uHouseID, HouseSoundID sound)
Definition: UIHouses.cpp:1036
HouseUI_CheckIfPlayerCanInteract
bool HouseUI_CheckIfPlayerCanInteract()
Definition: UIHouses.cpp:797
GUIButton::uW
unsigned int uW
Definition: GUIButton.h:26
BuildDialogueString
String BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, GameTime *a6)
Definition: GUIWindow.cpp:2189
AudioPlayer.h
uint8_t
unsigned __int8 uint8_t
Definition: SDL_config.h:35
UIShops.h
Point::y
unsigned int y
Definition: Point.h:8
GUIButton::msg_param
unsigned int msg_param
Definition: GUIButton.h:30
UIStatusBar.h
assets
AssetsManager * assets
Definition: AssetsManager.cpp:12
uint
unsigned int uint
Definition: MM7.h:4
uActiveCharacter
unsigned int uActiveCharacter
Definition: mm7_data.cpp:555
Localization::FormatString
String FormatString(unsigned int index,...) const
Definition: Localization.cpp:17
GUIButton::uY
unsigned int uY
Definition: GUIButton.h:22
GUIButton::uHeight
unsigned int uHeight
Definition: GUIButton.h:24
_2devent::fPriceMultiplier
float fPriceMultiplier
Definition: Events2D.h:53
GUIWindow::par1C
unsigned int par1C
Definition: GUIWindow.h:477
GameUI_StatusBar_OnEvent
void GameUI_StatusBar_OnEvent(const String &str, unsigned int num_seconds)
Definition: UIStatusBar.cpp:33
GUIWindow::ptr_1C
void * ptr_1C
Definition: GUIWindow.h:476
HouseSound_NotEnoughMoney_TrainingSuccessful
@ HouseSound_NotEnoughMoney_TrainingSuccessful
Definition: UIHouses.h:114
GUIWindow::DrawShops_next_generation_time_string
void DrawShops_next_generation_time_string(GameTime time)
Definition: GUIWindow.cpp:648
pMerchantsBuyPhrases
std::array< const char *, 7 > pMerchantsBuyPhrases
Definition: mm7_data.cpp:748
GUIWindow::GetControl
GUIButton * GetControl(unsigned int uID)
Definition: GUIWindow.cpp:311
guild_mambership_flags
std::array< int, 32 > guild_mambership_flags
Definition: mm7_data.cpp:480
GUIWindow::uFrameX
unsigned int uFrameX
Definition: GUIWindow.h:468
pAudioPlayer
AudioPlayer * pAudioPlayer
Definition: AudioPlayer.cpp:20
Localization::GetClassName
const char * GetClassName(unsigned int index) const
Definition: Localization.h:35
GUIWindow.h
Point
Definition: Point.h:3
ItemGen
Definition: Items.h:263
pMessageQueue_50CBD0
struct GUIMessageQueue * pMessageQueue_50CBD0
Definition: GUIWindow.cpp:86
pDialogueWindow
GUIWindow * pDialogueWindow
Definition: GUIWindow.cpp:50
Color16
uint16_t Color16(uint32_t r, uint32_t g, uint32_t b)
Definition: Engine.cpp:148
Party::SpellBooksInGuilds
std::array< std::array< ItemGen, 12 >, 32 > SpellBooksInGuilds
Definition: Party.h:316
String
std::string String
Definition: Strings.h:10
byte_4ED970_skill_learn_ability_by_class_table
std::array< std::array< char, 37 >, 36 > byte_4ED970_skill_learn_ability_by_class_table
Definition: mm7_data.cpp:425
Party::GetGold
int GetGold() const
Definition: Party.cpp:264
ItemsTable::pItems
NZIArray< ItemDesc, 800 > pItems
Definition: Items.h:460
Mouse.h
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52