added worldarea -> will be responsible for world map rendering
[dboe.git] / text.c
blob2fde250e5e65a25414b50a108bd3df87b9d1f70c
1 #define LINES_IN_TEXT_WIN 11
2 #define TEXT_BUF_LEN 70
4 #include <windows.h>
6 #include "global.h"
7 #include "stdio.h"
8 #include "text.h"
9 #include "string.h"
10 #include "locutils.h"
11 #include "fields.h"
12 #include "exlsound.h"
13 #include "graphutl.h"
16 char far *m_mage_sp[] = {"Spark","Minor Haste","Strength","Flame Cloud","Flame",
17 "Minor Poison","Slow","Dumbfound","Stinking Cloud","Summon Beast",
18 "Conflagration","Fireball","Weak Summoning","Web","Poison",
19 "Ice Bolt","Slow Group","Major Haste","Firestorm","Summoning",
20 "Shockstorm","Major Poison","Kill","Daemon","Major Blessing",
21 "Major Summoning","Shockwave"};
22 char far *m_priest_sp[] = {"Minor Bless","Light Heal","Wrack","Stumble","Bless",
23 "Curse","Wound","Summon Spirit","Disease","Heal",
24 "Holy Scourge","Smite","Curse All","Sticks to Snakes","Martyr's Shield",
25 "Bless All","Major Heal","Flamestrike","Summon Host","Heal All",
26 "Unholy Ravaging","Summon Guardian","Pestilence","Revive All","Avatar",
27 "Divine Thud"};
29 typedef struct {
30 char line[50];
31 } buf_line;
33 buf_line far text_buffer[TEXT_BUF_LEN];
34 short buf_pointer = 30, lines_to_print= 0, num_added_since_stop = 0;
35 char far store_string[256];
36 char far store_string2[256];
37 short start_print_point= 0;
38 short mark_where_printing_long;
39 Boolean printing_long = FALSE;
40 char far c_str[256] = "";
41 Boolean save_mess_given = FALSE;
43 RECT status_panel_clip_rect = {299, 11,495,175},item_panel_clip_rect = {297,11,463,175};
45 RECT far item_buttons_from[7] = {{0,12,14,24},{14,12,28,24},{28,12,42,24},{42,12,56,24},
46 {0,24,30,36},{30,24,60,36},{0,36,30,48}}; /**/
48 short store_mode;
49 Boolean string_added = FALSE;
50 short store_text_x = 0, store_text_y = 0;
51 extern short had_text_freeze,stat_screen_mode;
53 void InsetRect (RECT *rect, short x, short y);
55 // graphics globals
56 extern RECT status_panel_rect,status_panel_title_rect;
57 extern RECT text_panel_rect;
58 extern short overall_mode,which_combat_type,stat_window;
59 extern HWND mainPtr;
60 extern RECT more_info_button;
61 extern short which_item_page[6],current_cursor;
62 extern HCURSOR sword_curs;
63 extern HWND text_sbar,item_sbar;
64 extern POINT store_anim_ul;
65 extern HBRUSH bg[14];
66 extern short dest_personalities[40];
67 extern location source_locs[6];
68 extern location dest_locs[40] ;
70 extern HBITMAP mixed_gworld, pc_stats_gworld, item_stats_gworld, text_area_gworld,tiny_obj_gworld,party_template_gworld;
71 extern short terrain_there[9][9];
72 extern HBITMAP dialog_pattern_gworld,pattern_gworld,status_pattern_gworld,spec_scen_g;
74 // game globals
75 extern party_record_type far party;
76 extern piles_of_stuff_dumping_type *data_store;
77 extern piles_of_stuff_dumping_type2 *data_store2;
78 extern talking_record_type far talking;
79 extern scenario_data_type far scenario;
81 extern current_town_type far c_town;
82 extern outdoor_record_type far outdoors[2][2];
83 extern town_item_list far t_i;
84 extern unsigned char far out[96][96];
85 extern pc_record_type far adven[6];
86 extern big_tr_type far t_d;
87 extern short ulx,uly;
88 extern Boolean play_sounds,suppress_stat_screen,cartoon_happening;
89 extern RECT item_buttons[8][6];
90 // name, use, give, drip, info, sell/id
91 extern RECT pc_buttons[6][5];
92 // name, hp, sp, info, trade
93 extern Boolean item_area_button_active[8][6];
94 extern Boolean pc_area_button_active[6][5];
95 extern RECT item_screen_button_rects[9];
96 extern short spec_item_array[60];
97 extern short abil_chart[200],store_anim_type;
98 // combat globals
99 extern short item_bottom_button_active[9];
101 extern location pc_pos[6];
102 extern unsigned char far combat_terrain[64][64];
103 extern short current_pc;
104 extern short shop_identify_cost;
105 extern short store_selling_values[8];
106 extern short combat_posing_monster, current_working_monster; // 0-5 PC 100 + x - monster x
107 extern Boolean supressing_some_spaces;
108 extern location ok_space[4];
110 extern HFONT font,italic_font,underline_font,bold_font,small_bold_font;
111 extern HPALETTE hpal;
112 extern HDC main_dc;
113 extern HANDLE store_hInstance;
114 extern piles_of_stuff_dumping_type5 *data_store5;
116 short current_item_button[6] = {-1,-1,-1,-1,-1,-1};
117 short pc_button_state[6] = {-1,-1,-1,-1,-1,-1};
119 short text_pc_has_abil_equip(short pc_num,short abil)
121 short i = 0;
123 while (((adven[pc_num].items[i].variety == 0) || (adven[pc_num].items[i].ability != abil)
124 || (adven[pc_num].equip[i] == FALSE)) && (i < 24))
125 i++;
126 return i;
130 // Draws the pc area in upper right
131 //void win_draw_string(HWND dest_window,RECT dest_rect,char *str,short mode,short line_height)
132 void put_pc_screen()
134 char to_draw[256];
135 short dummy,i_num;
136 short i = 0,j,pc,weap1 = 16, weap2 = 16,skill_item,hit_adj,dam_adj;
137 RECT erase_rect = {2,17,270,99},to_draw_rect,from_rect;
138 RECT final_from_draw_rect = {0,0,271,116},final_to_draw_rect = {0,0,271,116};
139 RECT small_erase_rects[3] = {{34,101,76,114},{106,101,147,114},{174,101,201,114}};
140 Boolean has_type;
141 RECT pc_screen_help_button = {251,101,266,113};
142 RECT info_from = {1,0,13,12},switch_from = {12,0,25,12}; /**/
144 HDC hdc;
145 COLORREF colors[6] = {RGB(0,0,0),RGB(255,0,0),RGB(128,0,0),RGB(0,160,0),RGB(0,0,255),RGB(255,255,255)};
146 UINT c[6];
147 HBITMAP store_bmp;
148 Boolean right_buttons_same = TRUE;
150 for (i = 0; i < 6; i++)
151 if (((adven[i].main_status != 0) && (pc_button_state[i] != 1)) ||
152 ((adven[i].main_status == 0) && (pc_button_state[i] != 0)))
153 right_buttons_same = FALSE;
155 // First refresh gworld with the pc info
156 //rect_draw_some_item (orig_pc_info_screen_gworld, erase_rect, pc_info_screen_gworld, erase_rect, 0, 0);
157 // First clean up gworld with pretty patterns
158 // Will rewrite later
159 //FillCRECT(&erase_rect,bg[6]);
160 erase_rect.right -= 13;
161 //if (right_buttons_same == TRUE)
162 // erase_rect.right -= 15;
163 from_rect = erase_rect;
164 OffsetRect(&from_rect,-1 * from_rect.left,-1 * from_rect.top);
165 rect_draw_some_item(status_pattern_gworld,from_rect,
166 pc_stats_gworld,erase_rect,0,0);
167 //if (right_buttons_same == FALSE) {
168 erase_rect.left = erase_rect.right;
169 erase_rect.right += 13;
170 from_rect = erase_rect;
171 OffsetRect(&from_rect,-1 * from_rect.left,-1 * from_rect.top);
172 rect_draw_some_item(status_pattern_gworld,from_rect,
173 pc_stats_gworld,erase_rect,0,0);
174 // }
175 for (i = 0; i < 3; i++) {
176 // FillCRECT(&small_erase_rects[i],bg[7]);
177 from_rect = small_erase_rects[i];
178 OffsetRect(&from_rect,-1 * from_rect.left + 208,-1 * from_rect.top + 136);
179 rect_draw_some_item(mixed_gworld,from_rect,
180 pc_stats_gworld,small_erase_rects[i],0,0);
183 hdc = CreateCompatibleDC(main_dc);
184 //store_text_hdc = hdc;
185 SelectPalette(hdc,hpal,0);
186 SetBkMode(hdc,TRANSPARENT);
187 SelectObject(hdc,small_bold_font);
189 for (i = 0; i < 6; i++)
190 c[i] = GetNearestPaletteIndex(hpal,colors[i]);
191 store_bmp = SelectObject(hdc,pc_stats_gworld);
194 // Put food, gold, day
195 SetTextColor(hdc,PALETTEINDEX(c[5]));
196 sprintf((char *) to_draw, "%d", (short) party.gold);
197 win_draw_string(hdc,small_erase_rects[1],
198 to_draw,0,10);
199 sprintf((char *) to_draw, "%d", (short) party.food);
200 win_draw_string(hdc,small_erase_rects[0],
201 to_draw,0,10);
202 i = calc_day();
203 sprintf((char *) to_draw, "%d", i);
204 win_draw_string(hdc,small_erase_rects[2],
205 to_draw,0,10);
206 SetTextColor(hdc,PALETTEINDEX(c[0]));
208 for (i = 0; i < 6; i++) {
209 if (adven[i].main_status != 0) {
210 for (j = 0; j < 5; j++)
211 pc_area_button_active[i][j] = 1;
212 if (i == current_pc) {
213 //TextFace(italic | bold);
214 //ForeColor(blueColor);
215 SelectObject(hdc,italic_font);
216 SetTextColor(hdc,PALETTEINDEX(c[4]));
219 sprintf((char *) to_draw, "%d. %-20s ", i + 1, (char *) adven[i].name);
220 win_draw_string(hdc,pc_buttons[i][0],
221 to_draw,0,10);
222 //TextFace(bold);
223 //ForeColor(blackColor);
224 SelectObject(hdc,small_bold_font);
225 SetTextColor(hdc,PALETTEINDEX(c[0]));
227 to_draw_rect = pc_buttons[i][1];
228 to_draw_rect.right += 20;
229 switch (adven[i].main_status) {
230 case 1:
231 if (adven[i].cur_health == adven[i].max_health)
232 SetTextColor(hdc,PALETTEINDEX(c[3]));
233 else SetTextColor(hdc,PALETTEINDEX(c[1]));
234 sprintf((char *) to_draw, "%-3d ",adven[i].cur_health);
235 win_draw_string(hdc,pc_buttons[i][1],
236 to_draw,0,10);
237 if (adven[i].cur_sp == adven[i].max_sp)
238 SetTextColor(hdc,PALETTEINDEX(c[4]));
239 else SetTextColor(hdc,PALETTEINDEX(c[2]));
240 sprintf((char *) to_draw, "%-3d ",adven[i].cur_sp);
241 win_draw_string(hdc,pc_buttons[i][2],
242 to_draw,0,10);
243 SetTextColor(hdc,PALETTEINDEX(c[0]));
244 SelectObject(hdc,store_bmp);
245 draw_pc_effects(i,NULL);
246 SelectObject(hdc,pc_stats_gworld);
247 break;
248 case 2:
249 sprintf((char *) to_draw, "Dead");
250 break;
251 case 3:
252 sprintf((char *) to_draw, "Dust");
253 break;
254 case 4:
255 sprintf((char *) to_draw, "Stone");
256 break;
257 case 5:
258 sprintf((char *) to_draw, "Fled");
259 break;
260 case 6:
261 sprintf((char *) to_draw, "Surface");
262 break;
263 case 7:
264 sprintf((char *) to_draw, "Won");
265 break;
266 default:
267 sprintf((char *) to_draw, "Absent");
268 break;
270 if (adven[i].main_status != 1)
271 win_draw_string(hdc,to_draw_rect,
272 to_draw,0,10);
274 // Now put trade and info buttons
275 //rect_draw_some_item(mixed_gworld,info_from,pc_stats_gworld,pc_buttons[i][3],1,0);
276 //rect_draw_some_item(mixed_gworld,switch_from,pc_stats_gworld,pc_buttons[i][4],1,0);
277 // do faster!
278 to_draw_rect = pc_buttons[i][3];
279 to_draw_rect.right = pc_buttons[i][4].right + 1;
280 from_rect = info_from;
281 from_rect.right = from_rect.left + to_draw_rect.right - to_draw_rect.left;
283 pc_button_state[i] = 1;
284 SelectObject(hdc,store_bmp);
285 rect_draw_some_item(mixed_gworld,from_rect,pc_stats_gworld,to_draw_rect,1,0);
286 SelectObject(hdc,pc_stats_gworld);
289 else {
290 for (j = 0; j < 5; j++)
291 pc_area_button_active[i][j] = 0;
292 pc_button_state[i] = 0;
296 // Now put text on window.
297 SelectObject(hdc,store_bmp);
298 DeleteObject(hdc);
300 // Now put text on window.
301 OffsetRect(&final_to_draw_rect,PC_WIN_UL_X,PC_WIN_UL_Y);
302 rect_draw_some_item (pc_stats_gworld, final_from_draw_rect, pc_stats_gworld, final_to_draw_rect, 0, 1);
304 // Sometimes this gets called when character is slain. when that happens, if items for
305 // that PC are up, switch item page.
306 if ((current_pc < 6) && (adven[current_pc].main_status != 1) && (stat_window == current_pc)) {
307 set_stat_window(current_pc);
311 // Draws item area in middle right
312 // Screen_num is what page is visible in the item menu.
313 // 0 - 5 pc inventory 6 - special item 7 - missions
314 // Stat_screen_mode ... 0 - normal, adventuring, all buttons vis
315 // 1 - in shop, item info only
316 // 2 - in shop, identifying, shop_identify_cost is cost
317 // 3 - in shop, selling weapons
318 // 4 - in shop, selling armor
319 // 5 - in shop, selling all
320 // 6 - in shop, augmenting weapon,shop_identify_cost is type
321 void put_item_screen(short screen_num,short suppress_buttons)
322 // if suppress_buttons > 0, save time by not redrawing buttons
324 char pstats[256] = "Party stats:";
325 char to_draw[256];
326 short dummy,i_num,item_offset;
327 short i = 0,j,pc;
328 RECT erase_rect = {2,17,255,123},dest_rect,from_rect,to_rect;
329 RECT upper_frame_rect = {3,3,268,16};
330 Boolean has_type;
331 RECT parts_of_area_to_draw[3] = {{0,0,271,17},{0,16,256,123},{0,123,271,144}}; /**/
333 HDC hdc;
334 COLORREF colors[6] = {RGB(0,0,0),RGB(255,0,0),RGB(128,0,0),RGB(0,160,0),RGB(0,0,255),RGB(255,255,255)};
335 UINT c[6];
336 HBITMAP store_bmp;
338 // First refresh gworld with the pc info
339 //rect_draw_some_item (orig_pc_info_screen_gworld, erase_rect, pc_info_screen_gworld, erase_rect, 0, 0);
340 // First clean up gworld with pretty patterns
341 // Will rewrite later
342 //FillCRECT(&erase_rect,bg[6]);
343 from_rect = erase_rect;
344 OffsetRect(&from_rect,-1 * from_rect.left,-1 * from_rect.top);
345 rect_draw_some_item(status_pattern_gworld,from_rect,
346 item_stats_gworld,erase_rect,0,0);
347 if (suppress_buttons == 0)
348 for (i = 0; i < 6; i++)
349 if ((adven[i].main_status != 1) && (current_item_button[i] != -1)) {
350 current_item_button[i] = -1;
351 //FillCRECT(&item_screen_button_rects[i],bg[7]);
352 from_rect = item_screen_button_rects[i];
353 OffsetRect(&from_rect,-1 * from_rect.left + 208,-1 * from_rect.top + 136);
354 rect_draw_some_item(mixed_gworld,from_rect,
355 item_stats_gworld,item_screen_button_rects[i],0,0);
357 //FillCRECT(&upper_frame_rect,bg[7]);
358 to_rect = upper_frame_rect;
359 to_rect.right = to_rect.left + 96;
360 from_rect = to_rect;
361 OffsetRect(&from_rect,-1 * from_rect.left + 208,-1 * from_rect.top + 136);
362 rect_draw_some_item(mixed_gworld,from_rect,
363 item_stats_gworld,to_rect,0,0);
364 OffsetRect(&to_rect,96,0);
365 from_rect = to_rect;
366 OffsetRect(&from_rect,-1 * from_rect.left + 208,-1 * from_rect.top + 136);
367 rect_draw_some_item(mixed_gworld,from_rect,
368 item_stats_gworld,to_rect,0,0);
371 hdc = CreateCompatibleDC(main_dc);
372 //store_text_hdc = hdc;
373 SelectPalette(hdc,hpal,0);
374 SetBkMode(hdc,TRANSPARENT);
375 SelectObject(hdc,small_bold_font);
377 for (i = 0; i < 6; i++)
378 c[i] = GetNearestPaletteIndex(hpal,colors[i]);
381 store_bmp = SelectObject(hdc,item_stats_gworld);
383 // Draw buttons at bottom
384 if (suppress_buttons == 0) {
385 //for (i = 0; i < 6; i++)
386 // FillCRECT(&item_screen_button_rects[i],bg[7]);
389 item_offset = GetScrollPos(item_sbar,SB_CTL);
390 SetTextColor(hdc,PALETTEINDEX(c[5]));
392 for (i = 0; i < 8; i++)
393 for (j = 0; j < 6; j++)
394 item_area_button_active[i][j] = FALSE;
396 switch (screen_num) {
397 case 6: // On special items page
398 //TextFace(bold);
399 SelectObject(hdc,bold_font);
400 sprintf((char *) to_draw, "Special items:");
401 win_draw_string(hdc,upper_frame_rect,
402 to_draw,0,10);
403 SetTextColor(hdc,PALETTEINDEX(c[0]));
404 for (i = 0; i < 8; i++) {
405 i_num = i + item_offset;
406 if (spec_item_array[i_num] >= 0){
407 strcpy((char *) to_draw,data_store5->scen_strs[60 + spec_item_array[i_num] * 2]);
408 win_draw_string(hdc,item_buttons[i][0],to_draw,0,10);
410 SelectObject(hdc,store_bmp);
411 place_item_button(3,i,4,0);
412 if ((scenario.special_items[spec_item_array[i_num]] % 10 == 1)
413 && (!(is_combat())))
414 place_item_button(0,i,3,0);
415 SelectObject(hdc,item_stats_gworld);
418 break;
419 case 7: // On jobs page
420 break;
422 default: // on an items page
423 pc = screen_num;
424 sprintf((char *) to_draw, "%s inventory:",
425 (char *) adven[pc].name);
426 win_draw_string(hdc,upper_frame_rect,
427 to_draw,0,10);
429 SetTextColor(hdc,PALETTEINDEX(c[0]));
430 for (i = 0; i < 8; i++) {
431 i_num = i + item_offset;
432 sprintf((char *) to_draw, "%d.",i_num + 1);
433 win_draw_string(hdc,item_buttons[i][0],
434 to_draw,0,10);
436 dest_rect = item_buttons[i][0];
437 dest_rect.left += 36;
439 if (adven[pc].items[i_num].variety == 0) {
442 else {
443 if (adven[pc].equip[i_num] == TRUE) {
444 //TextFace(italic | bold);
445 SelectObject(hdc,italic_font);
446 if (adven[pc].items[i_num].variety < 3)
447 SetTextColor(hdc,PALETTEINDEX(c[1]));
448 else if ((adven[pc].items[i_num].variety >= 12) && (adven[pc].items[i_num].variety <= 17))
449 SetTextColor(hdc,PALETTEINDEX(c[3]));
450 else SetTextColor(hdc,PALETTEINDEX(c[4]));
452 else SetTextColor(hdc,PALETTEINDEX(c[0]));
453 // Place object graphic here
454 //if (adven[pc].items[i_num].variety != 0)
455 // draw_obj_graphic(i + ((which_item_page[pc] == 1) ? 1 : 0),adven[pc].items[i_num].graphic_num,text_panel_rect); // rect is space holder
457 if (is_ident(adven[pc].items[i_num]) == 0)
458 sprintf((char *) to_draw, "%s ",adven[pc].items[i_num].name);
459 else { /// Don't place # of charges when Sell button up and space tight
460 if ((adven[pc].items[i_num].charges > 0) && (adven[pc].items[i_num].type != 2)
461 && (stat_screen_mode <= 1))
462 sprintf((char *) to_draw, "%s (%d)",adven[pc].items[i_num].full_name,adven[pc].items[i_num].charges);
463 else sprintf((char *) to_draw, "%s",adven[pc].items[i_num].full_name);
465 dest_rect.left -= 2;
466 win_draw_string(hdc,dest_rect,to_draw,0,10);
467 //TextFace(0);
468 //TextFace(bold);
469 //ForeColor(blackColor);
470 SelectObject(hdc,small_bold_font);
471 SetTextColor(hdc,PALETTEINDEX(c[0]));
473 // this is kludgy, awkwark, and has redundant code. Done this way to
474 // make go faster, and I got lazy.
475 SelectObject(hdc,store_bmp);
476 if ((stat_screen_mode == 0) &&
477 ((is_town()) || (is_out()) || ((is_combat()) && (pc == current_pc)))) { // place give and drop and use
478 place_item_button(0,i,0,adven[pc].items[i_num].graphic_num); // item_graphic
479 if (abil_chart[adven[pc].items[i_num].ability] != 4) // place use if can
480 place_item_button(10,i,1,0);
481 else place_item_button(11,i,1,0);
483 else {
484 place_item_button(0,i,0,adven[pc].items[i_num].graphic_num); // item_graphic
485 place_item_button(3,i,4,0); // info button
486 if ((stat_screen_mode == 0) &&
487 ((is_town()) || (is_out()) || ((is_combat()) && (pc == current_pc)))) { // place give and drop and use
488 place_item_button(1,i,2,0);
489 place_item_button(2,i,3,0);
490 if (abil_chart[adven[pc].items[i_num].ability] != 4) // place use if can
491 place_item_button(0,i,1,0);
494 if (stat_screen_mode > 1) {
495 place_buy_button(i,pc,i_num,hdc);
498 SelectObject(hdc,item_stats_gworld);
500 } // end of if item is there
501 } // end of for (i = 0; i < 8; i++)
502 break;
505 // Now put text on window.
506 SelectObject(hdc,store_bmp);
507 DeleteObject(hdc);
509 place_item_bottom_buttons();
511 // Now put text on window.
512 for (i = 0; i < 3; i++) {
513 dest_rect = parts_of_area_to_draw[i];
514 OffsetRect(&dest_rect,ITEM_WIN_UL_X,ITEM_WIN_UL_Y);
515 rect_draw_some_item (item_stats_gworld, parts_of_area_to_draw[i],
516 item_stats_gworld, dest_rect, 0, 1);
520 void place_buy_button(short position,short pc_num,short item_num,HDC hdc)
522 RECT dest_rect,source_rect;
523 RECT button_sources[3] = {{0,24,30,36},{30,24,60,36},{0,36,30,48}}; /**/
524 short val_to_place;
525 short aug_cost[10] = {4,7,10,8, 15,15,10, 0,0,0};
526 HBITMAP store_bmp;
528 if (adven[pc_num].items[item_num].variety == 0)
529 return;
531 dest_rect = item_buttons[position][5];
533 val_to_place = (adven[pc_num].items[item_num].charges > 0) ?
534 adven[pc_num].items[item_num].charges * adven[pc_num].items[item_num].value :
535 adven[pc_num].items[item_num].value;
536 val_to_place = val_to_place / 2;
538 switch (stat_screen_mode) {
539 case 2:
540 if (is_ident(adven[pc_num].items[item_num]) == FALSE) {
541 item_area_button_active[position][5] = TRUE;
542 source_rect = button_sources[0];
543 val_to_place = shop_identify_cost;
545 break;
546 case 3: // sell weapons
547 if (((adven[pc_num].items[item_num].variety < 7) || (adven[pc_num].items[item_num].variety == 23) ||
548 (adven[pc_num].equip[item_num] == FALSE) &&
549 (adven[pc_num].items[item_num].variety == 24)) &&
550 (is_ident(adven[pc_num].items[item_num]) == TRUE) && (val_to_place > 0) &&
551 (is_cursed(adven[pc_num].items[item_num]) == FALSE)) {
552 item_area_button_active[position][5] = TRUE;
553 source_rect = button_sources[1];
555 break;
556 case 4: // sell armor
557 if ((adven[pc_num].items[item_num].variety >= 12) && (adven[pc_num].items[item_num].variety <= 17) &&
558 (adven[pc_num].equip[item_num] == FALSE) &&
559 (is_ident(adven[pc_num].items[item_num]) == TRUE) && (val_to_place > 0) &&
560 (is_cursed(adven[pc_num].items[item_num]) == FALSE)) {
561 item_area_button_active[position][5] = TRUE;
562 source_rect = button_sources[1];
564 break;
565 case 5: // sell any
566 if ((val_to_place > 0) && (is_ident(adven[pc_num].items[item_num]) == TRUE) &&
567 (adven[pc_num].equip[item_num] == FALSE) &&
568 (is_cursed(adven[pc_num].items[item_num]) == FALSE)) {
569 item_area_button_active[position][5] = TRUE;
570 source_rect = button_sources[1];
572 break;
573 case 6: // augment weapons
574 if ((adven[pc_num].items[item_num].variety < 3) &&
575 (is_ident(adven[pc_num].items[item_num]) == TRUE) &&
576 (adven[pc_num].items[item_num].ability == 0) &&
577 (is_magic(adven[pc_num].items[item_num]) == FALSE)) {
578 item_area_button_active[position][5] = TRUE;
579 source_rect = button_sources[2];
580 val_to_place = max(aug_cost[shop_identify_cost] * 100,adven[pc_num].items[item_num].value * (5 + aug_cost[shop_identify_cost]));
582 break;
584 if (item_area_button_active[position][5] == TRUE) {
585 store_selling_values[position] = val_to_place;
586 dest_rect = item_buttons[position][5];
587 dest_rect.right = dest_rect.left + 30;
588 rect_draw_some_item (mixed_gworld, source_rect,
589 item_stats_gworld, dest_rect, 1, 0);
590 sprintf((char *) store_string," %d",val_to_place);
591 //if (val_to_place >= 10000)
592 // TextFace(0);
593 store_bmp = SelectObject(hdc,item_stats_gworld);
594 char_win_draw_string(hdc,item_buttons[position][5],
595 store_string,2,10);
596 SelectObject(hdc,store_bmp);
597 //TextFace(bold);
601 //extern Boolean item_area_button_active[8][6];
602 // name, use, give, drop, info, sell/id
603 // shortcuts - if which_button_to_put is 10, all 4 buttons now
604 // if which_button_to_put is 11, just right 2
605 void place_item_button(short which_button_to_put,short which_slot,short which_button_position,short extra_val)
607 RECT from_rect = {0,0,18,18},to_rect;
609 if (which_button_position == 0) { // this means put little item graphic, extra val is which_graphic
610 item_area_button_active[which_slot][which_button_position] = TRUE;
611 OffsetRect(&from_rect,(extra_val % 10) * 18,(extra_val / 10) * 18);
612 to_rect = item_buttons[which_slot][0];
613 to_rect.right = to_rect.left + (to_rect.bottom - to_rect.top);
614 InsetRect(&to_rect,-1,-1);
615 OffsetRect(&to_rect,20,1);
616 InsetRect(&from_rect,2,2);
617 if (extra_val >= 150) {
618 from_rect = get_custom_rect(extra_val - 150);
619 rect_draw_some_item (spec_scen_g, from_rect,
620 item_stats_gworld, to_rect, 0, 0);
622 else {
623 rect_draw_some_item (tiny_obj_gworld, from_rect,
624 item_stats_gworld, to_rect, 1, 0);
626 return;
628 if (which_button_to_put < 4) { // this means put a regular item button
629 item_area_button_active[which_slot][which_button_position] = TRUE;
630 rect_draw_some_item (mixed_gworld, item_buttons_from[which_button_to_put],
631 item_stats_gworld, item_buttons[which_slot][which_button_position], 1, 0);
633 if (which_button_to_put == 10) { // this means put all 4
634 item_area_button_active[which_slot][1] = TRUE;
635 item_area_button_active[which_slot][2] = TRUE;
636 item_area_button_active[which_slot][3] = TRUE;
637 item_area_button_active[which_slot][4] = TRUE;
638 from_rect = item_buttons_from[0]; from_rect.right = item_buttons_from[3].right;
639 to_rect = item_buttons[which_slot][1];
640 to_rect.right = to_rect.left + from_rect.right - from_rect.left;
641 rect_draw_some_item (mixed_gworld, from_rect,
642 item_stats_gworld, to_rect, 1, 0);
644 if (which_button_to_put == 11) { // this means put right 3
645 item_area_button_active[which_slot][2] = TRUE;
646 item_area_button_active[which_slot][3] = TRUE;
647 item_area_button_active[which_slot][4] = TRUE;
648 from_rect = item_buttons_from[1]; from_rect.right = item_buttons_from[3].right;
649 to_rect = item_buttons[which_slot][2];
650 to_rect.right = to_rect.left + from_rect.right - from_rect.left;
651 rect_draw_some_item (mixed_gworld, from_rect,
652 item_stats_gworld, to_rect, 1, 0);
656 RECT get_custom_rect (short which_rect) ////
658 RECT store_rect = {0,0,28,36};
660 OffsetRect(&store_rect,28 * (which_rect % 10),36 * (which_rect / 10));
661 return store_rect;
664 void place_item_bottom_buttons()
666 RECT pc_from_rect = {0,0,28,36},but_from_rect = {36,85,54,101},to_rect; /**/
667 short i;
669 for (i = 0; i < 6; i++) {
670 if (adven[i].main_status == 1) {
671 item_bottom_button_active[i] = TRUE;
672 to_rect = item_screen_button_rects[i];
673 //if (current_item_button[i] != adven[i].which_graphic) {
674 current_item_button[i] = adven[i].which_graphic;
675 rect_draw_some_item (mixed_gworld, but_from_rect, item_stats_gworld, to_rect, 0, 0);
676 pc_from_rect = get_party_template_rect(i,0);
677 InsetRect(&to_rect,2,2);
678 rect_draw_some_item (party_template_gworld, pc_from_rect, item_stats_gworld, to_rect, 0, 0);
679 // }
682 else item_bottom_button_active[i] = FALSE;
686 RECT get_party_template_rect(short pc_num,short mode)
688 RECT source_rect;
690 source_rect.top = (pc_num % 3) * BITMAP_HEIGHT;
691 source_rect.bottom = 36 + (pc_num % 3) * BITMAP_HEIGHT;
692 source_rect.left = (pc_num / 3) * BITMAP_WIDTH * 2 + ((mode == 1) ? 28 : 0);
693 source_rect.right = source_rect.left + BITMAP_WIDTH;
695 return source_rect;
699 void set_stat_window(short new_stat)
701 short i,array_pos = 0;
703 stat_window = new_stat;
704 if ((stat_window < 6) && (adven[stat_window].main_status != 1))
705 stat_window = first_active_pc();
706 switch (stat_window) {
707 case 6:
708 for (i = 0; i < 60; i++)
709 spec_item_array[i] = -1;
710 for (i = 0; i < 50; i++) ////
711 if (party.spec_items[i] > 0) {
712 spec_item_array[array_pos] = i;
713 array_pos++;
715 array_pos = max(0,array_pos - 8);
716 //SetControlMaximum(item_sbar,array_pos);
717 SetScrollRange(item_sbar,SB_CTL,0,array_pos,FALSE);
718 break;
719 case 7:
720 SetScrollRange(item_sbar,SB_CTL,0,2,FALSE);
721 break;
722 default:
723 SetScrollRange(item_sbar,SB_CTL,0,16,FALSE);
724 break;
726 //SetControlValue(item_sbar,0);
727 SetScrollPos(item_sbar,SB_CTL,0,TRUE);
728 put_item_screen(stat_window,0);
732 short first_active_pc()
734 short i = 0;
736 for (i = 0; i < 6; i++)
737 if (adven[i].main_status == 1)
738 return i;
739 return 6;
743 void refresh_stat_areas(short mode)
745 short i,x;
746 RECT dest_rect,parts_of_area_to_draw[3] = {{0,0,271,17},{0,16,256,123},{0,123,271,144}};/**/
747 RECT pc_stats_from = {0,0,271,116},text_area_from = {0,0,256,138};
749 x = mode * 10;
750 dest_rect = pc_stats_from;
751 OffsetRect(&dest_rect,PC_WIN_UL_X,PC_WIN_UL_Y);
752 rect_draw_some_item (pc_stats_gworld, pc_stats_from, pc_stats_gworld, dest_rect, x, 1);
753 for (i = 0; i < 3; i++) {
754 dest_rect = parts_of_area_to_draw[i];
755 OffsetRect(&dest_rect,ITEM_WIN_UL_X,ITEM_WIN_UL_Y);
756 rect_draw_some_item (item_stats_gworld, parts_of_area_to_draw[i],
757 item_stats_gworld, dest_rect, x, 1);
759 dest_rect = text_area_from;
760 OffsetRect(&dest_rect,TEXT_WIN_UL_X,TEXT_WIN_UL_Y);
761 rect_draw_some_item (text_area_gworld, text_area_from, text_area_gworld, dest_rect, x, 1);
766 short total_encumberance(short pc_num)
768 short store = 0,i,what_val;
770 for (i = 0; i < 24; i++)
771 if (adven[pc_num].equip[i] == TRUE) {
772 what_val = adven[pc_num].items[i].awkward;
773 store += what_val;
775 return store;
778 short get_tnl(pc_record_type *pc)
780 short tnl = 100,i,store_per = 100;
781 short rp[3] = {0,12,20};
782 short ap[15] = {10,20,8,10,4, 6,10,7,12,15, -10,-8,-8,-20,-8};
784 tnl = (tnl * (100 + rp[pc->race])) / 100;
785 for (i = 0; i < 15; i++)
786 if (pc->traits[i] == TRUE)
787 store_per = store_per + ap[i];
789 tnl = (tnl * store_per) / 100;
791 return tnl;
796 void draw_pc_effects(short pc,HDC dest_dc)
797 //short pc; // 10 + x -> draw for pc x, but on spell dialog
799 RECT source_rects[18] = {{55,0,67,12},{55,12,67,24},{55,24,67,36},
800 {67,0,79,12},{67,12,79,24},{67,24,79,36},
801 {79,0,91,12},{79,12,91,24},{79,24,91,36},
802 {91,0,103,12},{91,12,103,24},{91,24,103,36},
803 {103,0,115,12},{103,12,115,24},{103,24,115,36},
804 {115,0,127,12},{115,12,127,24},{115,24,127,36}};
805 RECT dest_rect = {18,15,30,27},dlog_dest_rect = {66,354,78,366};//rects altered below
806 Boolean on_dialog = FALSE;
807 short right_limit = 250;
808 short dest = 0; // 0 - in gworld 2 - on dialog
809 short name_width,i,mode = 1;
810 HBITMAP dest_bmp;
812 for (i = 0; i < 18; i++)
813 alter_rect(&source_rects[i]);
814 alter_rect(&dest_rect);
815 alter_rect(&dlog_dest_rect);
817 if (pc >= 10) {
818 pc -= 10;
819 right_limit = 490;
820 dest_rect = dlog_dest_rect;
821 dest = 2;
822 mode = 0;
823 dest_rect.top += pc * 24 + 18;
824 dest_rect.bottom += pc * 24 + 18;
825 dest_bmp = (HBITMAP) dest_dc;
827 else {
828 name_width = string_length(adven[pc].name,main_dc);
829 right_limit = pc_buttons[0][1].left - 5;
830 //dest_rect.left = pc_buttons[i][1].left - 16;
831 dest_rect.left = name_width + 33;
832 dest_rect.right = dest_rect.left + 12;
833 dest_rect.top += pc * 13;
834 dest_rect.bottom += pc * 13;
835 dest_bmp = pc_stats_gworld;
838 if (adven[pc].main_status % 10 != 1)
839 return;
841 if ((adven[pc].status[0] > 0) && (dest_rect.right < right_limit)) {
842 rect_draw_some_item (mixed_gworld,source_rects[4],dest_bmp,dest_rect,mode,dest);
843 dest_rect.left += 13;
844 dest_rect.right += 13;
846 if (adven[pc].status[1] > 0) {
847 rect_draw_some_item (mixed_gworld,source_rects[2],dest_bmp,dest_rect,mode,dest);
848 dest_rect.left += 13;
849 dest_rect.right += 13;
851 if (adven[pc].status[1] < 0) {
852 rect_draw_some_item (mixed_gworld,source_rects[3],dest_bmp,dest_rect,mode,dest);
853 dest_rect.left += 13;
854 dest_rect.right += 13;
856 if (adven[pc].status[2] > 0) {
857 rect_draw_some_item (mixed_gworld,source_rects[(adven[pc].status[2] > 4) ? 1 : 0],dest_bmp,dest_rect,mode,dest);
858 dest_rect.left += 13;
859 dest_rect.right += 13;
861 if (adven[pc].status[4] > 0) {
862 rect_draw_some_item (mixed_gworld,source_rects[5],dest_bmp,dest_rect,mode,dest);
863 dest_rect.left += 13;
864 dest_rect.right += 13;
866 if (adven[pc].status[3] > 0) {
867 rect_draw_some_item (mixed_gworld,source_rects[6],dest_bmp,dest_rect,mode,dest);
868 dest_rect.left += 13;
869 dest_rect.right += 13;
871 if (adven[pc].status[3] < 0) {
872 rect_draw_some_item (mixed_gworld,source_rects[8],dest_bmp,dest_rect,mode,dest);
873 dest_rect.left += 13;
874 dest_rect.right += 13;
876 if ((adven[pc].status[5] > 0) && (dest_rect.right < right_limit)) {
877 rect_draw_some_item (mixed_gworld,source_rects[9],dest_bmp,dest_rect,mode,dest);
878 dest_rect.left += 13;
879 dest_rect.right += 13;
881 if ((adven[pc].status[6] > 0) && (dest_rect.right < right_limit)) {
882 rect_draw_some_item (mixed_gworld,source_rects[10],dest_bmp,dest_rect,mode,dest);
883 dest_rect.left += 13;
884 dest_rect.right += 13;
886 if ((adven[pc].status[7] > 0) && (dest_rect.right < right_limit)){
887 rect_draw_some_item (mixed_gworld,source_rects[11],dest_bmp,dest_rect,mode,dest);
888 dest_rect.left += 13;
889 dest_rect.right += 13;
891 if ((adven[pc].status[8] > 0) && (dest_rect.right < right_limit)){
892 rect_draw_some_item (mixed_gworld,source_rects[12],dest_bmp,dest_rect,mode,dest);
893 dest_rect.left += 13;
894 dest_rect.right += 13;
896 if ((adven[pc].status[9] > 0) && (dest_rect.right < right_limit)){
897 rect_draw_some_item (mixed_gworld,source_rects[13],dest_bmp,dest_rect,mode,dest);
898 dest_rect.left += 13;
899 dest_rect.right += 13;
901 if ((adven[pc].status[10] > 0) && (dest_rect.right < right_limit)){
902 rect_draw_some_item (mixed_gworld,source_rects[14],dest_bmp,dest_rect,mode,dest);
903 dest_rect.left += 13;
904 dest_rect.right += 13;
906 if ((adven[pc].status[11] > 0) && (dest_rect.right < right_limit)){
907 rect_draw_some_item (mixed_gworld,source_rects[15],dest_bmp,dest_rect,mode,dest);
908 dest_rect.left += 13;
909 dest_rect.right += 13;
911 if ((adven[pc].status[12] > 0) && (dest_rect.right < right_limit)){
912 rect_draw_some_item (mixed_gworld,source_rects[16],dest_bmp,dest_rect,mode,dest);
913 dest_rect.left += 13;
914 dest_rect.right += 13;
916 if ((adven[pc].status[13] > 0) && (dest_rect.right < right_limit)){
917 rect_draw_some_item (mixed_gworld,source_rects[17],dest_bmp,dest_rect,mode,dest);
918 dest_rect.left += 13;
919 dest_rect.right += 13;
924 void print_party_stats() {
925 add_string_to_buf("PARTY STATS:");
926 sprintf((char *) store_string, " Number of kills: %ld ", party.total_m_killed);
927 add_string_to_buf((char *) store_string);
928 if ((is_town()) || ((is_combat()) && (which_combat_type == 1))) {
929 sprintf((char *) store_string, " Kills in this town: %d ", party.m_killed[c_town.town_num]);
930 add_string_to_buf((char *) store_string);
932 sprintf((char *) store_string, " Total experience: %ld ", party.total_xp_gained);
933 add_string_to_buf((char *) store_string);
934 sprintf((char *) store_string, " Total damage done: %ld ", party.total_dam_done);
935 add_string_to_buf((char *) store_string);
936 sprintf((char *) store_string, " Total damage taken: %ld ", party.total_dam_taken);
937 add_string_to_buf((char *) store_string);
938 print_buf();
942 short do_look(location space)
944 short i,j,num_items = 0;
945 Boolean gold_here = FALSE, food_here = FALSE, is_lit = TRUE;
946 location from_where;
948 from_where = get_cur_loc();
949 is_lit = pt_in_light(from_where,space);
951 if (((is_out()) && (same_point(space,party.p_loc) == TRUE)) ||
952 ((is_town()) && (same_point(space,c_town.p_loc))))
953 add_string_to_buf(" Your party");
954 if (is_combat())
955 for (i = 0; i < 6; i++)
956 if ((same_point(space,pc_pos[i]) == TRUE) && (adven[i].main_status == 1)
957 && (is_lit == TRUE) && (can_see(pc_pos[current_pc],space,0) < 5)) {
958 sprintf((char *) store_string, " %s", (char *) adven[i].name);
959 add_string_to_buf((char *) store_string);
962 if (is_out() == FALSE) {
963 for (i = 0; i < T_M; i++)
964 if ((c_town.monst.dudes[i].active != 0) && (is_lit == TRUE)
965 && (monst_on_space(space,i) == TRUE) &&
966 ((is_town()) || (can_see(pc_pos[current_pc],space,0) < 5))
967 && (c_town.monst.dudes[i].m_d.picture_num != 0)) {
970 get_m_name(store_string2,c_town.monst.dudes[i].number);
971 if (c_town.monst.dudes[i].m_d.health < c_town.monst.dudes[i].m_d.m_health) {
972 if (c_town.monst.dudes[i].attitude % 2 == 1)
973 sprintf((char *) store_string, " Wounded %s (H)", store_string2);
974 else sprintf((char *) store_string, " Wounded %s (F)", store_string2);
976 else {
977 if (c_town.monst.dudes[i].attitude % 2 == 1)
978 sprintf((char *) store_string, " %s (H)", (char *) store_string2);
979 else sprintf((char *) store_string, " %s (F)", (char *) store_string2);
982 add_string_to_buf((char *) store_string);
986 if (is_out()) {
987 for (i = 0; i < 10; i++) {
988 if ((party.out_c[i].exists == TRUE)
989 && (same_point(space,party.out_c[i].m_loc) == TRUE)) {
990 for (j = 0; j < 7; j++)
991 if (party.out_c[i].what_monst.monst[j] != 0) {
992 get_m_name(store_string2,party.out_c[i].what_monst.monst[j]);
993 sprintf((char *) store_string, " %s", store_string2);
994 add_string_to_buf((char *) store_string);
995 j = 7;
1002 if (out_boat_there(space) < 30)
1003 add_string_to_buf(" Boat ");
1004 if (out_horse_there(space) < 30)
1005 add_string_to_buf(" Horse ");
1008 if (is_out() == FALSE) {
1009 if (town_boat_there(space) < 30)
1010 add_string_to_buf(" Boat ");
1011 if (town_horse_there(space) < 30)
1012 add_string_to_buf(" Horse ");
1014 if (is_web(space.x,space.y))
1015 add_string_to_buf(" Web ");
1016 if (is_crate(space.x,space.y))
1017 add_string_to_buf(" Crate ");
1018 if (is_barrel(space.x,space.y))
1019 add_string_to_buf(" Barrel ");
1020 if (is_fire_barrier(space.x,space.y))
1021 add_string_to_buf(" Magic Barrier ");
1022 if (is_force_barrier(space.x,space.y))
1023 add_string_to_buf(" Magic Barrier ");
1024 if (is_quickfire(space.x,space.y))
1025 add_string_to_buf(" Quickfire ");
1026 if (is_fire_wall(space.x,space.y))
1027 add_string_to_buf(" Wall of Fire ");
1028 if (is_force_wall(space.x,space.y))
1029 add_string_to_buf(" Wall of Force ");
1030 if (is_antimagic(space.x,space.y))
1031 add_string_to_buf(" Antimagic Field ");
1032 if (is_scloud(space.x,space.y))
1033 add_string_to_buf(" Stinking Cloud ");
1034 if (is_ice_wall(space.x,space.y))
1035 add_string_to_buf(" Ice Wall ");
1036 if (is_blade_wall(space.x,space.y))
1037 add_string_to_buf(" Blade Wall ");
1039 if (is_small_blood(space.x,space.y))
1040 add_string_to_buf(" Blood stain ");
1041 if (is_medium_blood(space.x,space.y))
1042 add_string_to_buf(" Blood stain ");
1043 if (is_large_blood(space.x,space.y))
1044 add_string_to_buf(" Blood stain ");
1045 if (is_small_slime(space.x,space.y))
1046 add_string_to_buf(" Smears of slime ");
1047 if (is_big_slime(space.x,space.y))
1048 add_string_to_buf(" Smears of slime ");
1049 if (is_ash(space.x,space.y))
1050 add_string_to_buf(" Ashes ");
1051 if (is_bones(space.x,space.y))
1052 add_string_to_buf(" Bones ");
1053 if (is_rubble(space.x,space.y))
1054 add_string_to_buf(" Rubble ");
1056 for (i = 0; i < NUM_TOWN_ITEMS; i++) {
1057 if ((t_i.items[i].variety != 0) && (same_point(space,t_i.items[i].item_loc) == TRUE)
1058 && (is_lit == TRUE)) {
1059 if (t_i.items[i].variety == 3)
1060 gold_here = TRUE;
1061 else if (t_i.items[i].variety == 11)
1062 food_here = TRUE;
1063 else num_items++;
1066 if (gold_here == TRUE)
1067 add_string_to_buf(" Gold");
1068 if (food_here == TRUE)
1069 add_string_to_buf(" Food");
1070 if (num_items > 8)
1071 add_string_to_buf(" Many items");
1072 else for (i = 0; i < NUM_TOWN_ITEMS; i++) {
1073 if ((t_i.items[i].variety != 0) && (t_i.items[i].variety != 3) &&(t_i.items[i].variety != 11) &&
1074 (same_point(space,t_i.items[i].item_loc) == TRUE) && (is_contained(t_i.items[i]) == FALSE)) {
1075 if (is_ident(t_i.items[i]) == TRUE)
1076 sprintf((char *) store_string, " %s",t_i.items[i].full_name);
1077 else sprintf((char *) store_string, " %s",t_i.items[i].name);
1078 add_string_to_buf((char *) store_string);
1083 if (is_lit == FALSE) {
1084 add_string_to_buf(" Dark ");
1085 return 0;
1088 return print_terrain(space);
1091 short town_boat_there(location where)
1093 short i;
1095 // Num boats stores highest # of boat in town
1096 for (i = 0; i < 30; i++)
1097 if ((party.boats[i].exists == TRUE) && (party.boats[i].which_town == c_town.town_num)
1098 && (same_point(where,party.boats[i].boat_loc) == TRUE))
1099 return i;
1100 return 30;
1102 short out_boat_there(location where)
1104 short i;
1106 for (i = 0; i < 30; i++)
1107 if ((party.boats[i].exists == TRUE) && (same_point(where,party.boats[i].boat_loc) == TRUE)
1108 && (party.boats[i].which_town == 200))
1109 return i;
1110 return 30;
1113 short town_horse_there(location where)
1115 short i;
1117 // Num boats stores highest # of boat in town
1118 for (i = 0; i < 30; i++)
1119 if ((party.horses[i].exists == TRUE) && (party.horses[i].which_town == c_town.town_num)
1120 && (same_point(where,party.horses[i].horse_loc) == TRUE))
1121 return i;
1122 return 30;
1124 short out_horse_there(location where)
1126 short i;
1128 for (i = 0; i < 30; i++)
1129 if ((party.horses[i].exists == TRUE) && (same_point(where,party.horses[i].horse_loc) == TRUE)
1130 && (party.horses[i].which_town == 200))
1131 return i;
1132 return 30;
1134 void notify_out_combat_began(out_wandering_type encounter,short *nums)
1136 short i;
1138 sprintf((char *) store_string, "COMBAT! ");
1139 add_string_to_buf((char *) store_string);
1141 for (i = 0; i < 6; i++)
1142 if (encounter.monst[i] != 0) {
1143 switch (encounter.monst[i]) {
1144 ////
1146 default:
1147 get_m_name(store_string2,encounter.monst[i]);
1148 sprintf((char *) store_string, " %d x %s ",nums[i],store_string2);
1149 break;
1151 add_string_to_buf((char *) store_string);
1153 if (encounter.monst[6] != 0) {
1154 get_m_name(store_string2,encounter.monst[6]);
1155 sprintf((char *) store_string, " %s ",store_string2);
1156 add_string_to_buf((char *) store_string);
1160 void get_m_name(char *str,unsigned char num)
1162 char store_name[256];
1164 strcpy((char *) str,(char *) data_store2->scen_item_list.monst_names[num]);
1166 void get_ter_name(char *str,unsigned char num)
1168 char store_name[256];
1170 ////
1171 if ((num == 90) && ((is_out()) || (is_town()) || ((is_combat()) && (which_combat_type == 1))))
1172 sprintf((char *) store_name,"Pit");
1173 else {
1174 strcpy((char *) store_name,(char *) data_store2->scen_item_list.ter_names[num]);
1176 strcpy((char *) str,(char *) store_name);
1179 void print_monst_name(unsigned char m_type)
1181 get_m_name(store_string2,m_type);
1182 sprintf ((char *) store_string, "%s:",store_string2);
1183 add_string_to_buf((char *) store_string);
1186 void print_monst_attacks(unsigned char m_type,short target)
1187 //short target; // < 100 - pc >= 100 monst
1189 char store_string3[60];
1191 get_m_name(store_string2,m_type);
1192 if (target < 100)
1193 sprintf ((char *) store_string, "%s attacks %s",
1194 store_string2,(char *) adven[target].name);
1195 else {
1196 get_m_name(store_string3,c_town.monst.dudes[target - 100].number);
1197 sprintf ((char *) store_string, "%s attacks %s",
1198 store_string2,store_string3);
1200 add_string_to_buf((char *) store_string);
1203 void damaged_message(short damage,short type)
1205 char str[256];
1207 get_str(str,20,130 + type);
1208 sprintf ((char *) store_string, " %s for %d",
1209 (char *) str,damage);
1210 add_string_to_buf((char *) store_string);
1213 // This prepares the monster's string for the text bar
1214 void print_monster_going(char *combat_str,unsigned char m_num,short ap)
1216 get_m_name(store_string2,m_num);
1217 sprintf ((char *) combat_str, "%s (ap: %d)",
1218 store_string2,ap);
1221 void monst_spell_note(unsigned char number,short which_mess)
1223 get_m_name(store_string2,number);
1224 switch (which_mess) {
1225 case 1:
1226 sprintf ((char *) store_string, " %s scared. ",store_string2);break;
1228 case 2:
1229 sprintf ((char *) store_string, " %s slowed. ",store_string2);break;
1231 case 3:
1232 sprintf ((char *) store_string, " %s weakened.",store_string2);break;
1234 case 4:
1235 sprintf ((char *) store_string, " %s poisoned.",store_string2);break;
1237 case 5:
1238 sprintf ((char *) store_string, " %s cursed.",store_string2);break;
1240 case 6:
1241 sprintf ((char *) store_string, " %s ravaged.",store_string2);break;
1243 case 7:
1244 sprintf ((char *) store_string, " %s undamaged.",store_string2);break;
1246 case 8:
1247 sprintf ((char *) store_string, " %s is stoned.",store_string2);break;
1248 case 9:
1249 sprintf ((char *) store_string, " Gazes at %s.",store_string2);break;
1250 case 10:
1251 sprintf ((char *) store_string, " %s resists.",store_string2);break;
1252 case 11:
1253 sprintf ((char *) store_string, " Drains %s.",store_string2);break;
1254 case 12:
1255 sprintf ((char *) store_string, " Shoots at %s.",store_string2);break;
1256 case 13:
1257 sprintf ((char *) store_string, " Throws spear at %s.",
1258 store_string2);
1259 break;
1260 case 14:
1261 sprintf ((char *) store_string, " Throws rock at %s.",
1262 store_string2);
1263 break;
1264 case 15:
1265 sprintf ((char *) store_string, " Throws razordisk at %s.",
1266 store_string2);
1267 break;
1268 case 16:
1269 sprintf ((char *) store_string, " Hits %s.",
1270 store_string2);
1271 break;
1272 case 17:
1273 sprintf ((char *) store_string, "%s disappears.",
1274 store_string2);
1275 break;
1276 case 18:
1277 sprintf ((char *) store_string, " Misses %s.",
1278 store_string2);
1279 break;
1280 case 19:
1281 sprintf ((char *) store_string, " %s is webbed.",store_string2);break;
1282 case 20:
1283 sprintf ((char *) store_string, " %s chokes.",store_string2);break;
1284 case 21:
1285 sprintf ((char *) store_string, " %s summoned.",store_string2);break;
1286 case 22:
1287 sprintf ((char *) store_string, " %s is dumbfounded.",store_string2);break;
1288 case 23:
1289 sprintf ((char *) store_string, " %s is charmed.",store_string2);break;
1290 case 24:
1291 sprintf ((char *) store_string, " %s is recorded.",store_string2);break;
1292 case 25:
1293 sprintf ((char *) store_string, " %s is diseased.",store_string2);break;
1294 case 26:
1295 sprintf ((char *) store_string, " %s is an avatar!",store_string2);break;
1296 case 27:
1297 sprintf ((char *) store_string, " %s splits!",store_string2);break;
1298 case 28:
1299 sprintf ((char *) store_string, " %s falls asleep.",store_string2);break;
1300 case 29:
1301 sprintf ((char *) store_string, " %s wakes up.",store_string2);break;
1302 case 30:
1303 sprintf ((char *) store_string, " %s paralyzed.",store_string2);break;
1304 case 31:
1305 sprintf ((char *) store_string, " %s covered with acid.",store_string2);break;
1306 case 32:
1307 sprintf ((char *) store_string, " Fires spines at %s.",store_string2);break;
1310 if (which_mess > 0)
1311 add_string_to_buf((char *) store_string);
1314 void monst_cast_spell_note(unsigned char number,short spell,short type)
1315 //short type; // 0 - mage 1- priest
1317 get_m_name(store_string2,number);
1318 sprintf ((char *) store_string, "%s casts:",
1319 (char *) store_string2);
1320 add_string_to_buf((char *) store_string);
1321 sprintf ((char *) store_string, " %s",
1322 (type == 1) ? (char *) m_priest_sp[spell - 1] : (char *) m_mage_sp[spell - 1]);
1323 add_string_to_buf((char *) store_string);
1326 void monst_breathe_note(unsigned char number)
1328 get_m_name(store_string2,number);
1329 sprintf ((char *) store_string, "%s breathes.",
1330 (char *) store_string2);
1331 add_string_to_buf((char *) store_string);
1335 void monst_damaged_mes(short which_m,short how_much,short how_much_spec)
1337 get_m_name(store_string2,c_town.monst.dudes[which_m].number);
1338 if (how_much_spec > 0)
1339 sprintf ((char *) store_string, " %s takes %d+%d",
1340 store_string2, how_much,how_much_spec);
1341 else sprintf ((char *) store_string, " %s takes %d",
1342 store_string2, how_much);
1344 add_string_to_buf((char *) store_string);
1347 void monst_killed_mes(short which_m)
1349 get_m_name(store_string2,c_town.monst.dudes[which_m].number);
1350 sprintf ((char *) store_string, " %s dies.",
1351 (char *) store_string2);
1352 add_string_to_buf((char *) store_string);
1355 void print_nums(short a,short b,short c)
1357 sprintf((char *) store_string, "debug: %d %d %d", a,b,c);
1358 add_string_to_buf((char *) store_string);
1362 short print_terrain(location space)
1364 unsigned char which_terrain;
1366 if (is_out()) {
1367 which_terrain = out[space.x][space.y];
1369 if (is_town()) {
1370 which_terrain = t_d.terrain[space.x][space.y];
1372 if (is_combat()) {
1373 which_terrain = combat_terrain[space.x][space.y];
1375 get_ter_name(store_string2,which_terrain);
1376 sprintf((char *) store_string, " %s", store_string2);
1377 add_string_to_buf((char *) store_string);
1379 return (short) which_terrain;
1383 //void add_string_to_buf(char *string)
1384 void add_string_to_buf(char const *string)
1386 //SetControlValue(text_sbar,58);
1387 SetScrollPos(text_sbar,SB_CTL,58,TRUE);
1388 string_added = TRUE;
1389 if (buf_pointer == mark_where_printing_long) {
1390 printing_long = TRUE;
1391 print_buf();
1392 through_sending();
1394 sprintf((char *)text_buffer[buf_pointer].line, "%-49.49s", string);
1395 text_buffer[buf_pointer].line[49] = 0;
1396 // c2pstr((char *)text_buffer[buf_pointer].line);
1397 if (buf_pointer == (TEXT_BUF_LEN - 1))
1398 buf_pointer = 0;
1399 else buf_pointer++;
1402 void init_buf()
1404 short i;
1406 for (i = 0; i < TEXT_BUF_LEN; i++)
1407 sprintf((char *) text_buffer[buf_pointer].line, " ");
1413 void print_buf ()
1415 short num_lines_printed = 0,ctrl_val;
1416 short line_to_print;
1417 short start_print_point;
1418 Boolean end_loop = FALSE;
1419 RECT store_text_rect = {0,0,256,138},dest_rect,erase_rect = {1,1,255,137}; /**/
1420 RECT from_rect,to_rect;
1421 HDC hdc;
1422 HBITMAP store_bmp;
1425 if (string_added == TRUE) {
1427 // First clean up gworld with pretty patterns
1428 //FillCRECT(&erase_rect,bg[6]);
1429 InsetRect(&erase_rect,1,1); ////
1430 erase_rect.right++;
1431 to_rect = erase_rect;
1432 to_rect.bottom = to_rect.top + 128;
1433 from_rect = to_rect;
1434 OffsetRect(&from_rect,-1 * from_rect.left,-1 * from_rect.top);
1435 rect_draw_some_item(status_pattern_gworld,from_rect,
1436 text_area_gworld,to_rect,0,0);
1437 to_rect = erase_rect;
1438 to_rect.top = to_rect.bottom - 8;
1439 from_rect = to_rect;
1440 OffsetRect(&from_rect,-1 * from_rect.left,-1 * from_rect.top);
1441 rect_draw_some_item(status_pattern_gworld,from_rect,
1442 text_area_gworld,to_rect,0,0);
1445 hdc = CreateCompatibleDC(main_dc);
1446 //store_text_hdc = hdc;
1447 SelectPalette(hdc,hpal,0);
1448 SetBkMode(hdc,TRANSPARENT);
1449 SelectObject(hdc,small_bold_font);
1451 store_bmp = SelectObject(hdc,text_area_gworld);
1453 //ctrl_val = 58 - GetControlValue(text_sbar);
1454 ctrl_val = 58 - GetScrollPos(text_sbar,SB_CTL);
1455 start_print_point = buf_pointer - LINES_IN_TEXT_WIN - ctrl_val;
1456 if (start_print_point< 0)
1457 start_print_point= TEXT_BUF_LEN + start_print_point;
1458 line_to_print= start_print_point;
1460 while ((line_to_print!= buf_pointer) && (num_lines_printed < LINES_IN_TEXT_WIN)) {
1461 //MoveTo(4, 13 + 12 * num_lines_printed);
1462 //drawstring((char *) text_buffer[line_to_print].line);
1463 DrawString((char *) text_buffer[line_to_print].line,4,
1464 2 + 12 * num_lines_printed,hdc);
1465 num_lines_printed++;
1466 line_to_print++;
1467 if (line_to_print== TEXT_BUF_LEN) {
1468 line_to_print= 0;
1471 if ((num_lines_printed == LINES_IN_TEXT_WIN - 1) && (printing_long == TRUE)) {
1472 end_loop = FALSE;
1473 line_to_print= buf_pointer;
1479 // Now put text on window.
1480 SelectObject(hdc,store_bmp);
1481 DeleteObject(hdc);
1484 dest_rect = store_text_rect;
1486 OffsetRect(&dest_rect,TEXT_WIN_UL_X,TEXT_WIN_UL_Y);
1487 // Now put text on window.
1488 rect_draw_some_item (text_area_gworld, store_text_rect, text_area_gworld, dest_rect, 0, 1);
1489 string_added = FALSE;
1492 void restart_printing()
1494 lines_to_print = 0;
1495 //clear_text_panel();
1498 void restore_mode()
1500 overall_mode = store_mode;
1503 void through_sending()
1505 mark_where_printing_long = buf_pointer + LINES_IN_TEXT_WIN - 1;
1506 if (mark_where_printing_long > TEXT_BUF_LEN - 1)
1507 mark_where_printing_long -= TEXT_BUF_LEN;
1508 printing_long = FALSE;
1511 void Display_String(char *str)
1513 char str2[256];
1515 // //c2pstr((char *) str);
1516 // sprintf((char *)str2," %s",str);
1517 // str2[0] = (char) strlen((char *)str);
1518 // DrawString(str2);
1521 void display_string(char *str)
1523 // c2pstr(str);
1524 // drawstring(str);
1527 /* Draw a bitmap in the world window. hor in 0 .. 8, vert in 0 .. 8,
1528 object is ptr. to bitmap to be drawn, and masking is for Copybits. */
1529 void Draw_Some_Item (HBITMAP src_gworld, RECT src_rect, HBITMAP targ_gworld,
1530 location target, char masked, short main_win)
1532 RECT destrec = {0,0,28,36};
1534 if ((target.x < 0) || (target.y < 0) || (target.x > 8) || (target.y > 8))
1535 return;
1536 if (src_gworld == NULL)
1537 return;
1538 if ((supressing_some_spaces == TRUE) &&
1539 (same_point(target,ok_space[0]) == FALSE) &&
1540 (same_point(target,ok_space[1]) == FALSE) &&
1541 (same_point(target,ok_space[2]) == FALSE) &&
1542 (same_point(target,ok_space[3]) == FALSE))
1543 return;
1544 terrain_there[target.x][target.y] = -1;
1546 destrec = coord_to_rect(target.x,target.y);
1547 rect_draw_some_item ( src_gworld, src_rect, targ_gworld,
1548 destrec, masked, main_win);
1552 RECT coord_to_rect(short i,short j)
1554 RECT to_return;
1556 to_return.left = 13 + BITMAP_WIDTH * i;
1557 to_return.right = to_return.left + BITMAP_WIDTH;
1558 to_return.top = 13 + BITMAP_HEIGHT * j;
1559 to_return.bottom = to_return.top + BITMAP_HEIGHT;
1561 return to_return;
1565 void c2p(char *str)
1569 void p2c(char *str)
1573 void get_str(char *str,short i, short j)
1575 GetIndString(str, i, j);
1576 p2c(str);
1579 short string_length(char *str,HDC hdc)
1581 short text_len[257];
1582 short total_width = 0,i,len;
1583 char p_str[256];
1585 for (i = 0; i < 257; i++)
1586 text_len[i]= 0;
1588 strcpy((char *) p_str,str);
1589 MeasureText(256,p_str,text_len,hdc);
1590 len = strlen((char *)str);
1592 //print_nums(text_len[1],text_len[2],text_len[3]);
1593 //print_nums(text_len[10],text_len[20],text_len[30]);
1594 for (i = 0; i < 257; i++)
1595 if ((text_len[i] > total_width) && (i <= len))
1596 total_width = text_len[i];
1597 return total_width;
1601 void char_win_draw_string(HDC dest_window,RECT dest_rect,char *str,short mode,short line_height)
1603 char store_s[256];
1605 strcpy((char *) store_s,str);
1606 win_draw_string( dest_window, dest_rect,store_s, mode, line_height);
1610 // mode: 0 - align up and left, 1 - center on one line
1611 // str is a c string, 256 characters
1612 // uses current font
1613 void win_draw_string(HDC dest_hdc,RECT dest_rect,char *str,short mode,short line_height)
1615 short i;
1617 // this will need formatting for '|' line breaks
1618 for (i = 0; i < 256; i++) {
1619 if (str[i] == 0)
1620 i = 256;
1621 else {
1622 if (str[i] == '|') {
1623 str[i] = 13;
1625 if (str[i] == '_')
1626 str[i] = 34;
1629 // if dest is main window, add ulx, uly
1630 if (dest_hdc == main_dc)
1631 OffsetRect(&dest_rect,ulx,uly);
1632 switch (mode) {
1633 case 0:
1634 dest_rect.bottom += 6;
1635 DrawText(dest_hdc,str,strlen((char *)str),&dest_rect,DT_LEFT | DT_NOPREFIX | DT_WORDBREAK); break;
1636 case 1:
1637 dest_rect.bottom += 6; dest_rect.top -= 6;
1638 DrawText(dest_hdc,str,strlen((char *)str),&dest_rect,
1639 DT_CENTER | DT_NOPREFIX | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE); break;
1640 case 2: case 3:
1641 dest_rect.bottom += 6; dest_rect.top -= 6;
1642 DrawText(dest_hdc,str,strlen((char *)str),&dest_rect,
1643 DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE); break;
1645 // not yet done adjusts for 1, 2, 3
1649 short calc_day()
1651 return (short) ((party.age) / 3700) + 1;
1654 Boolean day_reached(unsigned char which_day, unsigned char which_event)
1655 // which_day is day event should happen
1656 // which_event is the party.key_times value to cross reference with.
1657 // if the key_time is reached before which_day, event won't happen
1658 // if it's 8, event always happens
1659 // which_day gets an extra 20 days to give party bonus time
1661 short what_day;
1663 what_day = (short) (which_day) + 20;
1665 if ((which_event != 8) && (party.key_times[which_event] < what_day))
1666 return FALSE;
1667 if (calc_day() >= what_day)
1668 return TRUE;
1669 else return FALSE;
1673 // BEGIN EXTRA WINDOWS STUFF
1675 void WinDrawString(char *string,short x,short y)
1677 HDC hdc;
1678 COLORREF colors[2] = {RGB(0,0,0),RGB(255,255,255)};
1679 UINT c[2];
1681 c[0] = GetNearestPaletteIndex(hpal,colors[0]);
1682 c[1] = GetNearestPaletteIndex(hpal,colors[1]);
1684 hdc = GetDC(mainPtr);
1685 SelectPalette(hdc,hpal,0);
1686 SetViewportOrg(hdc,ulx,uly);
1687 SelectObject(hdc,small_bold_font);
1688 SetBkMode(hdc,TRANSPARENT);
1689 SetTextColor(hdc,PALETTEINDEX(c[1]));
1690 DrawString(string,x,y,hdc);
1691 fry_dc(mainPtr,hdc);
1694 void WinBlackDrawString(char *string,short x,short y)
1696 HDC hdc;
1698 hdc = GetDC(mainPtr);
1699 SelectPalette(hdc,hpal,0);
1700 SetViewportOrg(hdc,ulx,uly);
1701 SelectObject(hdc,small_bold_font);
1702 SetBkMode(hdc,TRANSPARENT);
1703 DrawString(string,x,y,hdc);
1704 fry_dc(mainPtr,hdc);
1708 void DrawString(char *string,short x,short y,HDC hdc)
1710 RECT text_r = {0,0,450,20};
1712 OffsetRect(&text_r,x,y);
1713 DrawText(hdc,string,-1,&text_r,DT_LEFT | DT_SINGLELINE | DT_TOP | DT_NOCLIP);
1717 //void Display_String(char *string) {
1718 //DrawString(string,store_x,store_y,store_text_hdc);
1721 void FlushEvents(short mode)
1722 // mode... 0 - keystrokes 1 - mouse presses 2 - both
1724 MSG msg;
1726 if ((mode == 0) || (mode == 2)) {
1727 while ((PeekMessage(&msg, mainPtr, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) != 0)
1730 if ((mode == 1) || (mode == 2)) {
1731 while ((PeekMessage(&msg, mainPtr, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) != 0)
1737 void ExitToShell()
1739 PostQuitMessage(0);
1742 void undo_clip()
1744 // RECT overall_rect = {0,0,530,435};
1745 HRGN rgn;
1747 rgn = CreateRectRgn(0,0,5000,5000);
1748 SelectClipRgn(main_dc,rgn);
1749 DeleteObject(rgn);
1752 void ClipRect(RECT *rect)
1754 HRGN rgn;
1755 HDC hdc;
1756 RECT rect2;
1758 rect2 = *rect;
1759 OffsetRect(&rect2,ulx,uly);
1761 rgn = CreateRectRgn(rect2.left,rect2.top,rect2.right,rect2.bottom);
1762 SelectClipRgn(main_dc,rgn);
1763 DeleteObject(rgn);
1766 void beep()
1768 long dummy;
1770 MessageBeep(MB_OK);
1771 Delay(30,&dummy);
1774 void SysBeep(short a)
1776 MessageBeep(MB_OK);
1779 void make_cursor_sword()
1781 SetCursor(sword_curs);
1785 void GetIndString(char *str,short i, short j) {
1786 UINT resnum = 0,len;
1787 short k;
1789 resnum = i * 300 + j;
1791 len = LoadString(store_hInstance,resnum,str,256);
1792 if (len == 0) {
1793 sprintf(str,"");
1794 return;
1796 for (k = 0; k < 256; k++) {
1797 if (str[k] == '|')
1798 str[k] = 13;
1799 if (str[k] == '_')
1800 str[k] = 34;
1804 void StringToNum(char *the_string,long *number_given) {
1805 long store_short;
1806 sscanf(the_string,"%ld",&store_short);
1807 *number_given = (long) store_short;
1810 void InsetRect(RECT *rect,short x, short y) {
1811 InflateRect(rect,-1 * x, -1 * y);
1814 void force_reprint()
1816 string_added = TRUE;
1819 // Note ... this expects a str len of at most 256 and
1820 // len_array pointing to a 256 long array of shorts
1821 void MeasureText(short str_len,char *str, short *len_array,HDC hdc)
1823 short text_len[257];
1824 short total_width = 0,i,len;
1825 char p_str[257];
1826 DWORD val_returned;
1827 char *store_array;
1828 short *store2;
1830 store_array = (char *) len_array;
1831 //text_len = len_array;
1832 for (i = 0; i < 256; i++)
1833 text_len[i] = 0;
1834 for (i = 1; i < str_len; i++) {
1835 strncpy(p_str,str,i);
1836 p_str[i] = 0;
1837 val_returned = GetTextExtent(hdc,p_str,i);
1838 text_len[i] = LOWORD(val_returned);
1840 for (i = 0; i < 256; i++) {
1841 store2 = (short *) store_array;
1842 *store2 = text_len[i];
1843 store_array += 2;
1847 // kludgy annoyance
1848 void MoveTo(short x, short y)
1850 store_text_x = x;
1851 store_text_y = y - 16;
1853 void MoveToDrawString(char *string,HDC hdc)
1855 DrawString(string,store_text_x,store_text_y, hdc);
1857 ////
1858 Boolean is_ident(item_record_type item)
1860 if (item.item_properties & 1)
1861 return TRUE;
1862 else return FALSE;
1864 Boolean is_magic(item_record_type item)
1866 if (item.item_properties & 4)
1867 return TRUE;
1868 else return FALSE;
1870 Boolean is_contained(item_record_type item)
1872 if (item.item_properties & 8)
1873 return TRUE;
1874 else return FALSE;
1876 Boolean is_cursed(item_record_type item)
1878 if (item.item_properties & 16)
1879 return TRUE;
1880 else return FALSE;
1882 Boolean is_property(item_record_type item)
1884 if (item.item_properties & 2)
1885 return TRUE;
1886 else return FALSE;