Files
oboe/Blades of Exile/boe.newgraph.cpp
Celtic Minstrel cf433e773d Well, at present the Windows code for the actual game almost compiles. The current goal is to undo all the things that Ormus did to make this job difficult.
Basically, remove as many as possible of the dependencies of the source files in the tools and classes folders on source files not in those folders.
(With the exception that files in the classes folder may depend on files in the tools folder.)

In this commit, several changes were made.
- Project file modified, may need further modification.
- Many files renamed to match the Mac version.
- #include statements for system headers changed to use <> instead of "" (some already did, but many didn't).
- xxx.h headers replaced with cxxx headers where appropriate.
- Most sound-related variables moved from globvars.cpp to soundvars.cpp.
- The files originally named graphutil and gutils have been merged.
- Changed TRUE/FALSE to true/false.
- Changed exlsound to soundtool and mostly removed dependencies on the main game files; the exception is that it still uses mainPtr (which probably can't be helped)
  and print_nums (which should probably be incorporated into the MessageBox string).
- Possibly other things that were forgotten.

For some reason this commit also includes changes recently committed into the branch for osx.

git-svn-id: http://openexile.googlecode.com/svn/trunk@121 4ebdad44-0ea0-11de-aab3-ff745001d230
2009-08-03 19:00:23 +00:00

1295 lines
42 KiB
C++

#include <Windows.h>
#include <cstring>
#include <cstdio>
#include "global.h"
#include "boe.graphics.h"
#include "boe.monster.h"
#include "tools/dlogtool.h"
#include "boe.newgraph.h"
#include "boe.fileio.h"
#include "boe.itemdata.h"
#include "boe.locutils.h"
#include "boe.fields.h"
#include "boe.text.h"
#include "tools/exlsound.h"
#include "boe.graphutil.h"
#include "globvar.h"
// Missile anim vars
typedef struct {
location dest;
short missile_type; // -1 no miss
short path_type,x_adj,y_adj;
} store_missile_type;
typedef struct {
location dest;
short val_to_place,offset;
short place_type; // 0 - on spot, 1 - random area near spot
short boom_type; // -1 no miss
short x_adj,y_adj;
} store_boom_type;
store_missile_type store_missiles[30];
store_boom_type store_booms[30];
Boolean have_missile,have_boom;
RECT explode_place_rect[30];
char last_light_mask[13][13];
void MoveTo(short x, short y)
{
store_text_x = x;
store_text_y = y - 16;
}
void apply_unseen_mask()
{
RECT base_rect = {8,10,43,53}/*{9,9,43,53}*/,to_rect,big_to = {13,13,265,337}; /**/
short i,j,k,l;
Boolean need_bother = FALSE;
HDC hdc;
HBITMAP store_bmp;
HBRUSH old_brush;
HPEN old_pen;
if (PSD[306][2] > 0)
return;
if ((is_combat()) && (which_combat_type == 0))
return;
if (!(is_out()) && (c_town.town.lighting > 0))
return;
for (i = 0; i < 11; i++)
for (j = 0; j < 11; j++)
if (unexplored_area[i + 1][j + 1] == 1)
need_bother = TRUE;
if (need_bother == FALSE)
return;
hdc = CreateCompatibleDC(main_dc);
SetBkMode(hdc,TRANSPARENT);
old_brush = (HBRUSH) SelectObject(hdc,checker_brush);
old_pen = (HPEN) SelectObject(hdc,GetStockObject(NULL_PEN));
SetROP2(hdc,R2_MASKPEN);
store_bmp = (HBITMAP) SelectObject(hdc,terrain_screen_gworld);
for (i = 0; i < 11; i++)
for (j = 0; j < 11; j++)
if (unexplored_area[i + 1][j + 1] == 1) {
to_rect = base_rect;
OffsetRect(&to_rect,-28 + i * 28 + 2,-36 + 36 * j);
//SectRect(&to_rect,&big_to,&to_rect);
IntersectRect(&to_rect,&to_rect,&big_to);
Rectangle(hdc, to_rect.left,to_rect.top,to_rect.right,to_rect.bottom);
//PaintRect(&to_rect);
for (k = i - 2; k < i + 1; k++)
for (l = j - 2; l < j + 1; l++)
if ((k >= 0) && (l >= 0) && (k < 9) && (l < 9) && ((k != i - 1) || (l != j - 1)))
terrain_there[k][l] = -1;
}
// Now put text on window.
SelectObject(hdc,old_brush);
SelectObject(hdc,old_pen);
SelectObject(hdc,store_bmp);
if (!DeleteDC(hdc)) DebugQuit("Cannot release DC 3");
}
void apply_light_mask()
{
RECT temp = {0,0,84,108},paint_rect,base_rect = {0,0,28,36};
RECT big_to = {13,13,265,337}; /**/
short i,j;
Boolean is_dark = FALSE,same_mask = TRUE;
HDC hdc;
HBITMAP store_bmp;
HBRUSH old_brush;
if (PSD[306][2] > 0)
return;
if (is_out())
return;
if (c_town.town.lighting == 0)
return;
if (oval_region == NULL) {
temp_rect_rgn = CreateRectRgn(0,0,0,0);
dark_mask_region = CreateRectRgn(0,0,0,0);
oval_region = CreateEllipticRgnIndirect(&temp);
}
// Process the light array
for (i = 2; i < 11; i++)
for (j = 2; j < 11; j++)
if (light_area[i][j] == 0) is_dark = TRUE;
if (is_dark == FALSE) {
for (i = 2; i < 11; i++)
for (j = 2; j < 11; j++)
last_light_mask[i][j] = 0;
return;
}
for (i = 1; i < 12; i++)
for (j = 1; j < 12; j++)
if ((light_area[i - 1][j - 1] >= 1) && (light_area[i + 1][j - 1] >= 1) &&
(light_area[i - 1][j] >= 1) && (light_area[i + 1][j] >= 1) &&
(light_area[i - 1][j + 1] >= 1) && (light_area[i + 1][j + 1] >= 1) &&
(light_area[i][j - 1] >= 1) && (light_area[i][j + 1] >= 1)) {
light_area[i][j] = 2;
}
for (i = 1; i < 12; i++)
for (j = 1; j < 12; j++)
if ((light_area[i - 1][j - 1] >= 2) && (light_area[i + 1][j - 1] >= 2) &&
(light_area[i - 1][j] >= 2) && (light_area[i + 1][j] >= 2) &&
(light_area[i - 1][j + 1] >= 2) && (light_area[i + 1][j + 1] >= 2) &&
(light_area[i][j - 1] >= 2) && (light_area[i][j + 1] >= 2)) {
light_area[i][j] = 3;
}
hdc = CreateCompatibleDC(main_dc);
SetBkMode(hdc,TRANSPARENT);
store_bmp = (HBITMAP) SelectObject(hdc,terrain_screen_gworld);
old_brush = (HBRUSH) SelectObject(hdc,GetStockObject(BLACK_BRUSH));
for (i = 2; i < 11; i++)
for (j = 2; j < 11; j++) {
if (light_area[i][j] == 1)
terrain_there[i - 2][j - 2] = -1;
}
for (i = 0; i < 13; i++)
for (j = 0; j < 13; j++)
if (last_light_mask[i][j] != light_area[i][j])
same_mask = FALSE;
if (same_mask == TRUE) {
PaintRgn(hdc,dark_mask_region);
SelectObject(hdc,store_bmp);
if (!DeleteDC(hdc)) DebugQuit("Cannot release DC 2");
return;
}
SetRectRgn(dark_mask_region,big_to.left,big_to.top,big_to.right,big_to.bottom);
for (i = 0; i < 13; i++)
for (j = 0; j < 13; j++)
last_light_mask[i][j] = light_area[i][j];
for (i = 1; i < 12; i++)
for (j = 1; j < 12; j++) {
if (light_area[i][j] == 2) {
OffsetRgn(oval_region,13 + 28 * (i - 3), 13 + 36 * (j - 3));
CombineRgn(dark_mask_region,dark_mask_region,oval_region,RGN_DIFF);
OffsetRgn(oval_region,-13 + -1 * (28 * (i - 3)),-13 + -1 * (36 * (j - 3)));
}
if (light_area[i][j] == 3) {
paint_rect = base_rect;
OffsetRect(&paint_rect,13 + 28 * (i - 2),13 + 36 * (j - 2));
SetRectRgn(temp_rect_rgn,paint_rect.left,paint_rect.top,
paint_rect.right + 28,paint_rect.bottom + 36);
CombineRgn(dark_mask_region,dark_mask_region,temp_rect_rgn,RGN_DIFF);
if (light_area[i + 1][j] == 3) light_area[i + 1][j] = 0;
if (light_area[i + 1][j + 1] == 3) light_area[i + 1][j + 1] = 0;
if (light_area[i][j + 1] == 3) light_area[i][j + 1] = 0;
}
}
PaintRgn(hdc,dark_mask_region);
SelectObject(hdc,store_bmp);
DeleteObject(hdc);
}
void start_missile_anim()
{
short i;
if (boom_anim_active == TRUE)
return;
boom_anim_active = TRUE;
for (i = 0; i < 30; i++) {
store_missiles[i].missile_type = -1;
store_booms[i].boom_type = -1;
}
for (i = 0; i < 6; i++)
pc_marked_damage[i] = 0;
for (i = 0; i < T_M; i++)
monst_marked_damage[i] = 0;
have_missile = FALSE;
have_boom = FALSE;
}
void end_missile_anim()
{
boom_anim_active = FALSE;
}
void add_missile(location dest,short missile_type,short path_type,short x_adj,short y_adj)
{
short i;
if (boom_anim_active == FALSE)
return;
if (PSD[306][2] > 0)
return;
// lose redundant missiles
for (i = 0; i < 30; i++)
if ((store_missiles[i].missile_type >= 0) && (same_point(dest,store_missiles[i].dest) == TRUE))
return;
for (i = 0; i < 30; i++)
if (store_missiles[i].missile_type < 0) {
have_missile = TRUE;
store_missiles[i].dest = dest;
store_missiles[i].missile_type =missile_type;
store_missiles[i].path_type =path_type;
store_missiles[i].x_adj =x_adj;
store_missiles[i].y_adj =y_adj;
return;
}
}
void run_a_missile(location from,location fire_to,short miss_type,short path,short sound_num,short x_adj,short y_adj,short len)
{
start_missile_anim();
add_missile(fire_to,miss_type,path, x_adj, y_adj);
do_missile_anim(len,from, sound_num);
end_missile_anim();
}
void run_a_boom(location boom_where,short type,short x_adj,short y_adj)
{
if ((type < 0) || (type > 2))
return;
start_missile_anim();
add_explosion(boom_where,-1,0,type, x_adj, y_adj);
do_explosion_anim(5,0);
end_missile_anim();
}
void mondo_boom(location l,short type)
{
short i;
start_missile_anim();
for (i = 0; i < 12; i++)
add_explosion(l,-1,1,type,0,0);
do_explosion_anim(5,0);
end_missile_anim();
}
void add_explosion(location dest,short val_to_place,short place_type,short boom_type,short x_adj,short y_adj)
{
short i;
if (PSD[306][2] > 0)
return;
if (boom_anim_active == FALSE)
return;
// lose redundant explosions
for (i = 0; i < 30; i++)
if ((store_booms[i].boom_type >= 0) && (same_point(dest,store_booms[i].dest) == TRUE)
&& (place_type == 0)) {
if (val_to_place > 0)
store_booms[i].val_to_place = val_to_place;
return;
}
for (i = 0; i < 30; i++)
if (store_booms[i].boom_type < 0) {
have_boom = TRUE;
store_booms[i].offset = (i == 0) ? 0 : -1 * get_ran(1,0,2);
store_booms[i].dest = dest;
store_booms[i].val_to_place = val_to_place;
store_booms[i].place_type = place_type;
store_booms[i].boom_type = boom_type;
store_booms[i].x_adj =x_adj;
store_booms[i].y_adj =y_adj;
return;
}
}
void do_missile_anim(short num_steps,location missile_origin,short sound_num)
{
RECT temp_rect,missile_origin_base = {1,1,17,17},active_area_rect,to_rect,from_rect;
short i,store_missile_dir;
POINT start_point,finish_point[30];
location screen_ul;
short x1[30],x2[30],y1[30],y2[30],t; // for path paramaterization
RECT missile_place_rect[30],missile_origin_rect[30],store_erase_rect[30];
POINT current_terrain_ul;
HBITMAP temp_gworld;
long delay_dummy;
RECT ter_scrn_rect = {0,0,279,351};
long t1,t2;
long pause_len = 0;
t2 = t1 = (long) GetCurrentTime();
if (sound_num == 11) pause_len = 660;
if (sound_num == 12) pause_len = 410;
if (sound_num == 14) pause_len = 200;
if (sound_num == 53) pause_len = 1000;
if (sound_num == 64) pause_len = 500;
if ((have_missile == FALSE) || (boom_anim_active == FALSE)) {
boom_anim_active = FALSE;
return;
}
for (i = 0; i < 30; i++)
if (store_missiles[i].missile_type >= 0)
i = 50;
if (i == 30)
return;
// initialize general data
current_terrain_ul.x = current_terrain_ul.y = 5;
// make terrain_template contain current terrain all nicely
draw_terrain(1);
to_rect = ter_scrn_rect;
OffsetRect(&to_rect,current_terrain_ul.x, current_terrain_ul.y);
rect_draw_some_item(terrain_screen_gworld,ter_scrn_rect,
terrain_screen_gworld,to_rect,0,1);
// create and clip temporary anim template
temp_rect = ter_scrn_rect;
temp_gworld = CreateCompatibleBitmap(main_dc,ter_scrn_rect.right,ter_scrn_rect.bottom);
active_area_rect = temp_rect;
InflateRect(&active_area_rect,-13,-13);
// init missile paths
for (i = 0; i < 30; i++) {
SetRectEmpty(&store_erase_rect[i]);
if ((store_missiles[i].missile_type >= 0) && (same_point(missile_origin,store_missiles[i].dest) == TRUE))
store_missiles[i].missile_type = -1;
}
screen_ul.x = center.x - 4; screen_ul.y = center.y - 4;
start_point.x = 13 + 14 + 28 * (short) (missile_origin.x - screen_ul.x);
start_point.y = 13 + 18 + 36 * (short) (missile_origin.y - screen_ul.y);
for (i = 0; i < 30; i++)
if (store_missiles[i].missile_type >= 0) {
finish_point[i].x = 1 + 13 + 14 + store_missiles[i].x_adj + 28 * (short) (store_missiles[i].dest.x - screen_ul.x);
finish_point[i].y = 1 + 13 + 18 + store_missiles[i].y_adj + 36 * (short) (store_missiles[i].dest.y - screen_ul.y);
// note ... +1 at beginning is put in to prevent infinite slope
if (store_missiles[i].missile_type < 7) {
store_missile_dir = get_missile_direction(start_point,finish_point[i]);
missile_origin_rect[i] = missile_origin_base;
OffsetRect(&missile_origin_rect[i],18 * store_missile_dir,18 * store_missiles[i].missile_type);
}
else {
missile_origin_rect[i] = missile_origin_base;
OffsetRect(&missile_origin_rect[i],0,18 * store_missiles[i].missile_type);
}
// x1 slope x2 start pt
x1[i] = finish_point[i].x - start_point.x;
x2[i] = start_point.x;
y1[i] = finish_point[i].y - start_point.y;
y2[i] = start_point.y;
}
else missile_place_rect[i].top =missile_place_rect[i].left =missile_place_rect[i].bottom =missile_place_rect[i].right = 0;
play_sound(-1 * sound_num);
// Now, at last, launch missile
for (t = 0; t < num_steps; t++) {
for (i = 0; i < 30; i++)
if (store_missiles[i].missile_type >= 0) {
// Where place?
temp_rect = missile_origin_base;
OffsetRect(&temp_rect,-8 + x2[i] + (x1[i] * t) / num_steps,
-8 + y2[i] + (y1[i] * t) / num_steps);
// now adjust for different paths
if (store_missiles[i].path_type == 1)
OffsetRect(&temp_rect,0,
-1 * (t * (num_steps - t)) / 100);
//SectRect(&temp_rect,&active_area_rect,&missile_place_rect[i]);
IntersectRect(&missile_place_rect[i],&temp_rect,&active_area_rect);
// Now put terrain in temporary;
rect_draw_some_item(terrain_screen_gworld,missile_place_rect[i],
temp_gworld,missile_place_rect[i],0,0);
// Now put in missile
from_rect = missile_origin_rect[i];
if (store_missiles[i].missile_type >= 7)
OffsetRect(&from_rect,18 * (t % 8),0);
rect_draw_some_item(missiles_gworld,from_rect,
temp_gworld,temp_rect,1,0);
}
// Now draw all missiles to screen
for (i = 0; i < 30; i++)
if (store_missiles[i].missile_type >= 0) {
to_rect = store_erase_rect[i];
OffsetRect(&to_rect,current_terrain_ul.x,current_terrain_ul.y);
rect_draw_some_item(terrain_screen_gworld,store_erase_rect[i],
terrain_screen_gworld,to_rect,0,1);
to_rect = missile_place_rect[i];
store_erase_rect[i] = to_rect;
OffsetRect(&to_rect,current_terrain_ul.x,current_terrain_ul.y);
rect_draw_some_item(temp_gworld,missile_place_rect[i],
temp_gworld,to_rect,0,1);
}
if ((PSD[306][6] == 3) || ((PSD[306][6] == 1) && (t % 4 == 0)) || ((PSD[306][6] == 2) && (t % 3 == 0)))
Delay(1,&delay_dummy);
}
// Exit gracefully, and clean up screen
for (i = 0; i < 30; i++)
store_missiles[i].missile_type = -1;
DeleteObject(temp_gworld);
to_rect = ter_scrn_rect;
OffsetRect(&to_rect,current_terrain_ul.x,current_terrain_ul.y);
rect_draw_some_item(terrain_screen_gworld,ter_scrn_rect,
terrain_screen_gworld,to_rect,0,1);
while (t2 - t1 < pause_len + 40) {
t2 = (long)GetCurrentTime();
}
play_sound(99);
}
short get_missile_direction(POINT origin_point,POINT the_point)
{
location store_dir;
short dir = 0;
// To reuse legacy code, will renormalize the_point, which is missile destination,
// so that origin_point is moved to (149,185) and the_point is moved in proportion
the_point.x += 149 - origin_point.x;
the_point.y += 185 - origin_point.y;
if ((the_point.x < 135) & (the_point.y >= ((the_point.x * 34) / 10) - 293)
& (the_point.y <= (-1 * ((the_point.x * 34) / 10) + 663)))
store_dir.x--;
if ((the_point.x > 163) & (the_point.y <= ((the_point.x * 34) / 10) - 350)
& (the_point.y >= (-1 * ((the_point.x * 34) / 10) + 721)))
store_dir.x++;
if ((the_point.y < 167) & (the_point.y <= (the_point.x / 2) + 102)
& (the_point.y <= (-1 * (the_point.x / 2) + 249)))
store_dir.y--;
if ((the_point.y > 203) & (the_point.y >= (the_point.x / 2) + 123)
& (the_point.y >= (-1 * (the_point.x / 2) + 268)))
store_dir.y++;
switch (store_dir.y) {
case 0:
dir = 4 - 2 * (store_dir.x); break;
case -1:
dir = (store_dir.x == -1) ? 7 : store_dir.x; break;
case 1:
dir = 4 - store_dir.x; break;
}
return dir;
}
void do_explosion_anim(short, short special_draw)
// sound_num currently ignored
// special_draw - 0 normal 1 - first half 2 - second half
{
RECT temp_rect,to_rect,from_rect;
RECT base_rect = {0,0,28,36},text_rect;
char str[256];
short i,temp_val,temp_val2;
location screen_ul;
short t,cur_boom_type = 0;
POINT current_terrain_ul;
HBITMAP temp_gworld;
long delay_dummy;
short boom_type_sound[3] = {5,10,53};
RECT ter_scrn_rect = {0,0,279,351};
HDC hdc;
COLORREF colors[5] = {RGB(0,0,0),RGB(255,0,0),RGB(128,0,0),RGB(0,160,0),RGB(255,255,255)};
HBITMAP store_bmp;
long t1,t2;
long snd_len[3] = {1500,1410,1100};
t2 = t1 = (long) GetCurrentTime();
if ((have_boom == FALSE) || (boom_anim_active == FALSE)) {
boom_anim_active = FALSE;
return;
}
for (i = 0; i < 30; i++)
if (store_booms[i].boom_type >= 0)
i = 50;
if (i == 30)
return;
// initialize general data
current_terrain_ul.x = current_terrain_ul.y = 5;
// make terrain_template contain current terrain all nicely
draw_terrain(1);
if (special_draw != 2) {
to_rect = ter_scrn_rect;
OffsetRect(&to_rect,current_terrain_ul.x, current_terrain_ul.y);
rect_draw_some_item(terrain_screen_gworld,ter_scrn_rect,
terrain_screen_gworld,to_rect,0,1);
}
// create and clip temporary anim template
temp_rect = ter_scrn_rect;
temp_gworld = CreateCompatibleBitmap(main_dc,ter_scrn_rect.right,ter_scrn_rect.bottom);
hdc = CreateCompatibleDC(main_dc);
SetBkMode(hdc,TRANSPARENT);
SelectObject(hdc,small_bold_font);
SetTextColor(hdc,colors[4]);
// init missile paths
screen_ul.x = center.x - 4; screen_ul.y = center.y - 4;
for (i = 0; i < 30; i++)
if ((store_booms[i].boom_type >= 0) && (special_draw < 2)) {
cur_boom_type = store_booms[i].boom_type;
explode_place_rect[i] = base_rect;
OffsetRect(&explode_place_rect[i],13 + 28 * (store_booms[i].dest.x - screen_ul.x) + store_booms[i].x_adj,
13 + 36 * (store_booms[i].dest.y - screen_ul.y) + store_booms[i].y_adj);
if ((store_booms[i].place_type == 1) && (special_draw < 2)) {
temp_val = get_ran(1,0,50) - 25;
temp_val2 = get_ran(1,0,50) - 25;
OffsetRect(&explode_place_rect[i],temp_val,temp_val2);
}
// eliminate stuff that's too gone.
IntersectRect(&temp_rect,&explode_place_rect[i],&ter_scrn_rect);
if (EqualRect(&temp_rect,&explode_place_rect[i]) == FALSE) {
store_booms[i].boom_type = -1;
}
}
else if (special_draw < 2)
explode_place_rect[i].top =explode_place_rect[i].left =explode_place_rect[i].bottom =explode_place_rect[i].right = 0;
if (special_draw < 2)
play_sound(boom_type_sound[cur_boom_type]);
// Now, at last, do explosion
for (t = (special_draw == 2) ? 6 : 0; t < ((special_draw == 1) ? 6 : 11); t++) { // t goes up to 10 to make sure screen gets cleaned up
// First, lay terrain in temporary graphic area;
for (i = 0; i < 30; i++)
if (store_booms[i].boom_type >= 0)
rect_draw_some_item(terrain_screen_gworld,explode_place_rect[i],
temp_gworld,explode_place_rect[i],0,0);
// Now put in explosions
for (i = 0; i < 30; i++)
if (store_booms[i].boom_type >= 0) {
if ((t + store_booms[i].offset >= 0) && (t + store_booms[i].offset <= 7)) {
from_rect = base_rect;
OffsetRect(&from_rect,28 * (t + store_booms[i].offset),144 + 36 * (store_booms[i].boom_type));
rect_draw_some_item(fields_gworld,from_rect,
temp_gworld,explode_place_rect[i],1,0);
if (store_booms[i].val_to_place > 0) {
text_rect = explode_place_rect[i];
text_rect.top += 2;
text_rect.left -= 2;
if (store_booms[i].val_to_place < 10)
text_rect.left += 4;
sprintf(str,"%d",store_booms[i].val_to_place);
store_bmp = (HBITMAP) SelectObject(hdc,temp_gworld);
char_win_draw_string(hdc,text_rect,str,1,12);
SelectObject(hdc,store_bmp);
}
}
}
// Now draw all missiles to screen
for (i = 0; i < 30; i++)
if (store_booms[i].boom_type >= 0) {
to_rect = explode_place_rect[i];
OffsetRect(&to_rect,current_terrain_ul.x,current_terrain_ul.y);
rect_draw_some_item(temp_gworld,explode_place_rect[i],
temp_gworld,to_rect,0,1);
}
Delay(2 * (1 + PSD[306][6]),&delay_dummy);
}
// Exit gracefully, and clean up screen
for (i = 0; i < 30; i++)
if (special_draw != 1)
store_booms[i].boom_type = -1;
SelectObject(hdc,store_bmp);
if (DeleteDC(hdc) == 0) DebugQuit("DeleteDC failed 1");
DeleteObject(temp_gworld);
if (special_draw != 1) {
while (t2 - t1 < snd_len[cur_boom_type] + 100) {
t2 = (long)GetCurrentTime();
}
play_sound(99);
}
}
/*
shop_type:
0 - weapon shop
1 - armor shop
2 - misc shop
3 - healer
4 - food
5-9 - magic shop
10 - mage spells
11 - priest spells
12 alchemy
*/
void click_shop_rect(RECT area_rect)
{
long dum;
draw_shop_graphics(1,area_rect);
if (play_sounds == TRUE) play_sound(37);
else Delay(5,&dum);
draw_shop_graphics(0,area_rect);
}
void draw_shop_graphics(short draw_mode,RECT clip_area_rect)
// mode 1 - drawing dark for button press
{
RECT area_rect,from_rect,item_info_from = {42,11,56,24};
RECT face_rect = {6,6,38,38};
RECT title_rect = {48,15,260,42};
RECT dest_rect,help_from = {126,23,142,36},done_from = {0,23,63,46}; /**/
short faces[13] = {1,1,1,42,43, 1,1,1,1,1, 44,44,44};
short i,what_chosen;
RECT shopper_name = {6,44,260,56};
short current_pos;
short cur_cost,what_magic_shop,what_magic_shop_item;
char cur_name[256];
char cur_info_str[256];
char *cost_strs[] =
{ "Extremely Cheap",
"Very Reasonable",
"Pretty Average",
"Somewhat Pricey",
"Expensive",
"Exorbitant",
"Utterly Ridiculous"
};
item_record_type base_item;
HDC hdc;
COLORREF colors[7] = {RGB(0,0,0),RGB(255,0,130),RGB(128,0,70),RGB(0,0,100),RGB(0,0,220),
RGB(0,220,0),RGB(255,110,255)};
HBITMAP store_bmp;
HBRUSH old_brush;
hdc = CreateCompatibleDC(main_dc);
SetBkMode(hdc,TRANSPARENT);
SelectObject(hdc,small_bold_font);
store_bmp = (HBITMAP) SelectObject(hdc,talk_gworld);
if (draw_mode > 0) {
IntersectClipRect(hdc,clip_area_rect.left,clip_area_rect.top,clip_area_rect.right,clip_area_rect.bottom);
}
area_rect = talk_area_rect;
OffsetRect(&area_rect,-5,-5);
old_brush = (HBRUSH) SelectObject(hdc,GetStockObject(NULL_BRUSH));
Rectangle(hdc,area_rect.left,area_rect.top,area_rect.right,area_rect.bottom);
SelectObject(hdc,old_brush);
InflateRect(&area_rect,-1,-1);
SelectObject(hdc,store_bmp);
if (draw_mode > 0) {
paint_pattern(talk_gworld,0,clip_area_rect,3);
}
else paint_pattern(talk_gworld,0,area_rect,3);
SelectObject(hdc,talk_gworld);
old_brush = (HBRUSH) SelectObject(hdc,GetStockObject(NULL_BRUSH));
Rectangle(hdc,shop_frame.left,shop_frame.top,shop_frame.right,shop_frame.bottom);
SelectObject(hdc,old_brush);
SelectObject(hdc,store_bmp);
// Place store icon
if (draw_mode == 0) {
i = faces[store_shop_type];
draw_dialog_graphic((HWND) talk_gworld, face_rect, 1000 + i, FALSE,1);
}
SelectObject(hdc,talk_gworld);
// Place name of store and shopper name
SelectObject(hdc,fantasy_font);
SetTextColor(hdc,colors[3]);
dest_rect = title_rect;
OffsetRect(&dest_rect,1,-5);
char_win_draw_string(hdc,dest_rect,store_store_name,2,18);
OffsetRect(&dest_rect,-1,-1);
SetTextColor(hdc,colors[4]);
char_win_draw_string(hdc,dest_rect,store_store_name,2,18);
SelectObject(hdc,small_bold_font);
SetTextColor(hdc,colors[3]);
switch (store_shop_type) {
case 3: sprintf(cur_name,"Healing for %s.",adven[current_pc].name); break;
case 10: sprintf(cur_name,"Mage Spells for %s.",adven[current_pc].name);break;
case 11: sprintf(cur_name,"Priest Spells for %s.",adven[current_pc].name); break;
case 12: sprintf(cur_name,"Buying Alchemy.");break;
case 4: sprintf(cur_name,"Buying Food.");break;
default:sprintf(cur_name,"Shopping for %s.",adven[current_pc].name); break;
}
char_win_draw_string(hdc,shopper_name,cur_name,2,18);
// Place help and done buttons
SetTextColor(hdc,colors[0]);
SelectObject(hdc,store_bmp);
talk_help_rect.right = talk_help_rect.left + help_from.right - help_from.left;
talk_help_rect.bottom = talk_help_rect.top + help_from.bottom - help_from.top;
rect_draw_some_item(dlg_buttons_gworld,help_from,talk_gworld,talk_help_rect,0,0);
rect_draw_some_item(dlg_buttons_gworld,done_from,talk_gworld,shop_done_rect,0,0);
SelectObject(hdc,talk_gworld);
if (draw_mode == 0)
SetTextColor(hdc,colors[0]);
else SetTextColor(hdc,colors[4]);
SelectObject(hdc,small_bold_font);
// Place all the items
for (i = 0; i < 8; i++) {
current_pos = i + GetScrollPos(shop_sbar,SB_CTL);
if (store_shop_items[current_pos] < 0)
break; // theoretically, this shouldn't happen
cur_cost = store_shop_costs[current_pos];
what_chosen = store_shop_items[current_pos];
SelectObject(hdc,store_bmp);
switch (what_chosen / 100) {
case 0: case 1: case 2: case 3: case 4:
base_item = get_stored_item(what_chosen);
base_item.item_properties = base_item.item_properties | 1;
draw_dialog_graphic((HWND) talk_gworld, shopping_rects[i][2],1800 + base_item.graphic_num, FALSE,1);
strcpy(cur_name,base_item.full_name);
get_item_interesting_string(base_item,cur_info_str);
break;
case 5:
base_item = store_alchemy(what_chosen - 500);
draw_dialog_graphic((HWND) talk_gworld, shopping_rects[i][2],1853, FALSE,1);//// all graphic nums
strcpy(cur_name,base_item.full_name);
sprintf(cur_info_str,"");
break;
case 6:
break;
case 7:
what_chosen -= 700;
draw_dialog_graphic((HWND) talk_gworld, shopping_rects[i][2],1879, FALSE,1);
strcpy(cur_name,heal_types[what_chosen]);
sprintf(cur_info_str,"");
break;
case 8:
base_item = store_mage_spells(what_chosen - 800 - 30);
draw_dialog_graphic((HWND)talk_gworld, shopping_rects[i][2],1800 + base_item.graphic_num, FALSE,1);
strcpy(cur_name,base_item.full_name);
sprintf(cur_info_str,"");
break;
case 9:
base_item = store_priest_spells(what_chosen - 900 - 30);
draw_dialog_graphic((HWND)talk_gworld, shopping_rects[i][2],1853, FALSE,1);
strcpy(cur_name,base_item.full_name);
sprintf(cur_info_str,"");
break;
default:
what_magic_shop = (what_chosen / 1000) - 1;
what_magic_shop_item = what_chosen % 1000;
base_item = party.magic_store_items[what_magic_shop][what_magic_shop_item];
base_item.item_properties = base_item.item_properties | 1;
draw_dialog_graphic((HWND)talk_gworld, shopping_rects[i][2],1800 + base_item.graphic_num, FALSE,1);
strcpy(cur_name,base_item.full_name);
get_item_interesting_string(base_item,cur_info_str);
break;
}
from_rect = item_info_from;
OffsetRect(&from_rect,0,1);
shopping_rects[i][6].bottom = shopping_rects[i][6].top +
(from_rect.bottom - from_rect.top);
if ((store_shop_type != 3) && (store_shop_type != 4))
rect_draw_some_item(mixed_gworld,item_info_from,talk_gworld,shopping_rects[i][6],1,0);
SelectObject(hdc,talk_gworld);
// Now draw item shopping_rects[i][7]
// 0 - whole area, 1 - active area 2 - graphic 3 - item name
// 4 - item cost 5 - item extra str 6 - item help button
char_win_draw_string(hdc,shopping_rects[i][3],cur_name,0,12);
sprintf(cur_name,"Cost: %d",cur_cost);
char_win_draw_string(hdc,shopping_rects[i][4],cur_name,0,12);
char_win_draw_string(hdc,shopping_rects[i][5],cur_info_str,0,12);
}
// Finally, cost info and help strs
sprintf(cur_name,"Prices here are %s.",cost_strs[store_cost_mult]);
char_win_draw_string(hdc,bottom_help_rects[0],cur_name,0,12);
char_win_draw_string(hdc,bottom_help_rects[1],"Click on item name (or type 'a'-'h') to buy.",0,12);
char_win_draw_string(hdc,bottom_help_rects[2],"Hit done button (or Esc.) to quit.",0,12);
if ((store_shop_type != 3) && (store_shop_type != 4))
char_win_draw_string(hdc,bottom_help_rects[3],"'I' button brings up description.",0,12);
SelectObject(hdc,store_bmp);
if (!DeleteDC(hdc)) DebugQuit("Cannot release DC 8");
refresh_shopping();
ShowScrollBar(shop_sbar,SB_CTL,TRUE);
}
void refresh_shopping()
{
RECT from_rects[4] = {{0,0,279,62},{0,62,253,352},{269,62,279,352},{0,352,279,415}},to_rect;
/**/
short i;
for (i = 0; i < 4; i++) {
to_rect = from_rects[i];
OffsetRect(&to_rect,5,5);
rect_draw_some_item(talk_gworld,from_rects[i],talk_gworld,to_rect,0,1);
}
}
void click_talk_rect(char *str_to_place,char *str_to_place2,RECT c_rect)
{
long dum;
place_talk_str(str_to_place,str_to_place2,1,c_rect);
if (play_sounds == TRUE)
play_sound(37);
else Delay(5,&dum);
place_talk_str(str_to_place,str_to_place2,0,c_rect);
}
item_record_type store_mage_spells(short which_s)
{
item_record_type spell = {21,0, 0,0,0,0,0,0, 53,0,0,0,0,0, 0, 0,0, location(),"", "",0,0,0,0};
short cost[32] = {150,200,150,1000,1200,400,300,200,
200,250,500,1500,300, 250,125,150,
400,450, 800,600,700,600,7500, 500,
5000,3000,3500,4000,4000,4500,7000,5000};
char str[256];
if (which_s != minmax(0,31,(int)which_s))
which_s = 0;
spell.item_level = which_s + 30;
spell.value = cost[which_s];
GetIndString(str,38,which_s + 1);
strcpy((char *)spell.full_name,(char *)str);
return spell;
}
// which_s = 0 means that it returns first 4th level spell
item_record_type store_priest_spells(short which_s)
{
item_record_type spell = {21,0, 0,0,0,0,0,0, 53,0,0,0,0,0, 0, 0,0, location(),"", "",0,0,0,0};
short cost[32] =
{100,150,75,400,200, 100,80,250,
400,400,1200,600,300, 600,350,250,
500,500,600,800, 1000,900,400,600,
2500,2000,4500,4500,3000,3000,2000,2000};
char str[256];
if (which_s != minmax(0,31,(int)which_s))
which_s = 0;
spell.item_level = which_s + 30;
spell.value = cost[which_s];
GetIndString(str,38,which_s + 50);
strcpy((char *)spell.full_name,(char *)str);
return spell;
}
item_record_type store_alchemy(short which_s)
{
item_record_type spell = {21,0, 0,0,0,0,0,0, 53,0,0,0,0,0, 0, 0,0, location(),"", "",0,0,0,0};
short val[20] = {50,75,30,130,100,150, 200,200,300,250,300, 500,600,750,700,1000,10000,5000,7000,12000};
char str[256];
if (which_s != minmax(0,19,(int)which_s))
which_s = 0;
spell.item_level = which_s;
spell.value = val[which_s];
GetIndString(str,38,which_s + 100);
strcpy((char *)spell.full_name,(char *)str);
return spell;
}
void get_item_interesting_string(item_record_type item,char *message)
{
if (item.isProperty())
{
sprintf(message,"Not yours.");
return;
}
if (item.isIdent() == false)
{
sprintf(message,"");
return;
}
if (item.isCursed())
{
sprintf(message,"Cursed item.");
return;
}
switch (item.variety) {
case 1: case 2: case 5: case 6: case 24: case 25: ////
if (item.bonus != 0)
sprintf(message,"Damage: 1-%d + %d.",item.item_level,item.bonus);
else sprintf(message,"Damage: 1-%d.",item.item_level);
break;
case 12: case 13: case 14: case 15: case 16: case 17:
sprintf(message,"Blocks %d-%d damage.",item.item_level + (item.protection > 0) ? 1 : 0,
item.item_level + item.protection);
break;
case 4: case 23:
sprintf(message,"Bonus : +%d to hit.",item.bonus);
break;
case 3:
sprintf(message,"%d gold pieces.",item.item_level);
break;
case 11:
sprintf(message,"%d food.",item.item_level);
break;
case 20:
sprintf(message,"Poison: Does %d-%d damage.",item.item_level,item.item_level * 6);
break;
default:
sprintf(message,"");
if (item.charges > 0)
sprintf(message,"Uses: %d",item.charges);
break;
}
if (item.charges > 0)
sprintf(message,"Uses: %d",item.charges);
}
void place_talk_str(char *str_to_place,char *str_to_place2,short color,RECT c_rect)
// color 0 - regular 1 - darker
{
RECT area_rect;
RECT face_rect = {6,6,38,38};
RECT title_rect = {48,19,260,42};
RECT dest_rect,help_from = {126,23,142,36}; /**/
short i,j,str_len,line_height = 18;
char p_str[256],str[256],str_to_draw[256],str_to_draw2[256];
short text_len[257],current_rect,store_last_word_break = 0,start_of_last_kept_word = -1;
short last_line_break = 0,last_word_break = 0,on_what_line = 0,last_stored_word_break = 0;
Boolean force_skip = FALSE;
short face_to_draw;
HDC hdc;
COLORREF colors[7] = {RGB(0,0,0),RGB(0,0,204),RGB(0,0,102),RGB(0,0,100),RGB(0,0,220),
RGB(51,153,51),RGB(0,204,0)};
HBITMAP store_bmp;
HBRUSH old_brush;
HFONT store_font;
hdc = CreateCompatibleDC(main_dc);
SetBkMode(hdc,TRANSPARENT);
store_font = (HFONT) SelectObject(hdc,fantasy_font);
store_bmp = (HBITMAP)SelectObject(hdc,talk_gworld);
if (c_rect.right > 0) {
IntersectClipRect(hdc,c_rect.left,c_rect.top,c_rect.right,c_rect.bottom);
}
area_rect = talk_area_rect;
OffsetRect(&area_rect,-5,-5);
old_brush = (HBRUSH) SelectObject(hdc,GetStockObject(NULL_BRUSH));
Rectangle(hdc,area_rect.left,area_rect.top,area_rect.right,area_rect.bottom);
SelectObject(hdc,old_brush);
InflateRect(&area_rect,-1,-1);
SelectObject(hdc,store_bmp);
if (c_rect.right > 0) {
paint_pattern(talk_gworld,0,c_rect,3);
}
else paint_pattern(talk_gworld,0,area_rect,3);
// Put help button
talk_help_rect.right = talk_help_rect.left + help_from.right - help_from.left;
talk_help_rect.bottom = talk_help_rect.top + help_from.bottom - help_from.top;
rect_draw_some_item(dlg_buttons_gworld,help_from,talk_gworld,talk_help_rect,0,0);
// Place face of talkee
if ((color == 0) && (c_rect.right == 0)) {
face_to_draw = scenario.scen_monsters[store_monst_type].default_facial_pic;
if (store_talk_face_pic >= 0)
face_to_draw = store_talk_face_pic;
if (store_talk_face_pic >= 1000) {
draw_dialog_graphic((HWND) talk_gworld, face_rect, 2400 + store_talk_face_pic - 1000, FALSE,1);
}
else {
i = get_monst_picnum(store_monst_type);
if (face_to_draw <= 0)
draw_dialog_graphic((HWND) talk_gworld, face_rect, 400 + i, FALSE,1);
else draw_dialog_graphic((HWND) talk_gworld, face_rect, 1000 + face_to_draw, FALSE,1);
}
}
SelectObject(hdc,talk_gworld);
// Place name oftalkee
SetTextColor(hdc,colors[3]);
dest_rect = title_rect;
OffsetRect(&dest_rect,1,-5);
char_win_draw_string(hdc,dest_rect,title_string,2,18);
OffsetRect(&dest_rect,-1,-1);
SetTextColor(hdc,colors[4]);
char_win_draw_string(hdc,dest_rect,title_string,2,18);
// Place buttons at bottom.
if (color == 0)
SetTextColor(hdc,colors[5]);
else SetTextColor(hdc,colors[6]);
if((PSD[307][1] == 1) && (talk_end_forced))
ShowWindow(talk_edit_box, SW_HIDE);
for (i = 0; i < 9; i++)
if ((talk_end_forced == FALSE) || (i == 6) || (i == 5)) {
OffsetRect(&preset_words[i].word_rect,0,-2);
char_win_draw_string(hdc,preset_words[i].word_rect,preset_words[i].word,2,18);
OffsetRect(&preset_words[i].word_rect,0,2);
}
// Place bulk of what said. Save words.
if (color == 0)
for (i = 0; i < 50; i++)
store_words[i].word_rect.left = store_words[i].word_rect.right = 0;
str_len = (short) strlen((char *)str_to_place);
if (str_len == 0) {
sprintf((char *) str_to_place,".");
}
strcpy((char *) str,str_to_place);
strcpy((char *) p_str,str_to_place);
for (i = 0; i < 257; i++)
text_len[i]= 0;
MeasureText(256,p_str,text_len,hdc);
dest_rect = word_place_rect;
current_rect = 0;
if (color == 0)
SetTextColor(hdc,colors[2]);
else SetTextColor(hdc,colors[1]);
MoveTo(dest_rect.left + 1 , dest_rect.top + 1 + line_height * on_what_line + 9);
for (i = 0;i < str_len;i++) {
if (((str[i] != 39) && ((str[i] < 65) || (str[i] > 122)) && ((str[i] < 48) || (str[i] > 57))) && (color == 0)) { // New word, so set up a rect
if (((i - store_last_word_break >= 4) || (i >= str_len - 1))
&& (i - last_stored_word_break >= 4) && (talk_end_forced == FALSE)) {
store_words[current_rect].word_rect.left = dest_rect.left + (text_len[store_last_word_break] - text_len[last_line_break]) - 2;
store_words[current_rect].word_rect.right = dest_rect.left + (text_len[i + 1] - text_len[last_line_break]) - 1;
store_words[current_rect].word_rect.top = dest_rect.top + 1 + line_height * on_what_line - 5;
store_words[current_rect].word_rect.bottom = dest_rect.top + 1 + line_height * on_what_line + 13;
if ((str[store_last_word_break] < 48) || (str[store_last_word_break] == 96)
|| (str[store_last_word_break] > 122)
|| ((str[store_last_word_break] >= 58) && (str[store_last_word_break] <= 64)))
store_last_word_break++;
store_words[current_rect].word[0] = str[store_last_word_break];
store_words[current_rect].word[1] = str[store_last_word_break + 1];
store_words[current_rect].word[2] = str[store_last_word_break + 2];
store_words[current_rect].word[3] = str[store_last_word_break + 3];
store_words[current_rect].word[4] = 0;
for (j = 0; j < 4; j++)
if ((store_words[current_rect].word[j] >= 65) && (store_words[current_rect].word[j] <= 90))
store_words[current_rect].word[j] += 32;
if (scan_for_response(store_words[current_rect].word) < 0) {
store_words[current_rect].word_rect.left = store_words[current_rect].word_rect.right = 0;
}
else {
start_of_last_kept_word = store_last_word_break;
if (current_rect < 49)
current_rect++;
}
last_stored_word_break = i + 1;
}
}
if (((text_len[i] - text_len[last_line_break] > (dest_rect.right - dest_rect.left - 6))
&& (last_word_break > last_line_break)) || (str[i] == '|') || (i == str_len - 1)) {
if (str[i] == '|') {
str[i] = ' ';
force_skip = TRUE;
}
store_last_word_break = last_word_break;
if (i == str_len - 1)
last_word_break = i + 2;
sprintf((char *)str_to_draw," ");
strncpy ((char *) str_to_draw,(char *) str + last_line_break,(size_t) (last_word_break - last_line_break - 1));
sprintf((char *)str_to_draw2," %s",str_to_draw);
str_to_draw2[0] = (char) strlen((char *)str_to_draw);
DrawString((str_to_draw2 + 1),store_text_x,store_text_y, hdc);
on_what_line++;
MoveTo(dest_rect.left + 1 , dest_rect.top + 1 + line_height * on_what_line + 9);
last_line_break = last_word_break;
if (force_skip == TRUE) {
force_skip = FALSE;
i++;
last_line_break++;
last_word_break++;
}
if ((start_of_last_kept_word >= last_line_break) && (current_rect > 0)) {
OffsetRect(&store_words[current_rect - 1].word_rect,5 + -1 * store_words[current_rect - 1].word_rect.left,line_height);
}
}
if (str[i] == ' ') { // New word
store_last_word_break = last_word_break = i + 1;
}
if (on_what_line == 17)
i = 10000;
}
// Now for string 2
str_len = (short) strlen((char *)str_to_place2);
start_of_last_kept_word = -1;
if (str_len > 0) {
strcpy((char *) str,str_to_place2);
strcpy((char *) p_str,str_to_place2);
for (i = 0; i < 257; i++)
text_len[i]= 0;
MeasureText(256,p_str,text_len,hdc);
last_line_break = store_last_word_break = last_word_break = last_stored_word_break = 0;
MoveTo(dest_rect.left + 1 , dest_rect.top + 1 + line_height * on_what_line + 9);
for (i = 0;i < str_len;i++) {
if (((str[i] != 39) && ((str[i] < 65) || (str[i] > 122)) && ((str[i] < 48) || (str[i] > 57))) && (color == 0)) { // New word, so set up a rect
if (((i - store_last_word_break >= 4) || (i >= str_len - 1))
&& (i - last_stored_word_break >= 4) && (talk_end_forced == FALSE)) {
store_words[current_rect].word_rect.left = dest_rect.left + (text_len[store_last_word_break] - text_len[last_line_break]) - 2;
store_words[current_rect].word_rect.right = dest_rect.left + (text_len[i + 1] - text_len[last_line_break]) - 1;
store_words[current_rect].word_rect.top = dest_rect.top + 1 + line_height * on_what_line - 5;
store_words[current_rect].word_rect.bottom = dest_rect.top + 1 + line_height * on_what_line + 13;
if ((str[store_last_word_break] < 48) || (str[store_last_word_break] == 96)
|| (str[store_last_word_break] > 122)
|| ((str[store_last_word_break] >= 58) && (str[store_last_word_break] <= 64)))
store_last_word_break++;
store_words[current_rect].word[0] = str[store_last_word_break];
store_words[current_rect].word[1] = str[store_last_word_break + 1];
store_words[current_rect].word[2] = str[store_last_word_break + 2];
store_words[current_rect].word[3] = str[store_last_word_break + 3];
store_words[current_rect].word[4] = 0;
for (j = 0; j < 4; j++)
if ((store_words[current_rect].word[j] >= 65) && (store_words[current_rect].word[j] <= 90))
store_words[current_rect].word[j] += 32;
if (scan_for_response(store_words[current_rect].word) < 0)
store_words[current_rect].word_rect.left = store_words[current_rect].word_rect.right = 0;
else {
start_of_last_kept_word = store_last_word_break;
if (current_rect < 49)
current_rect++;
}
last_stored_word_break = i + 1;
}
}
if (((text_len[i] - text_len[last_line_break] > (dest_rect.right - dest_rect.left - 6))
&& (last_word_break > last_line_break)) || (str[i] == '|') || (i == str_len - 1)) {
if (str[i] == '|') {
str[i] = ' ';
force_skip = TRUE;
}
store_last_word_break = last_word_break;
if (i == str_len - 1)
last_word_break = i + 2;
sprintf((char *)str_to_draw," ");
strncpy ((char *) str_to_draw,(char *) str + last_line_break,(size_t) (last_word_break - last_line_break - 1));
sprintf((char *)str_to_draw2," %s",str_to_draw);
str_to_draw2[0] = (char) strlen((char *)str_to_draw);
DrawString((str_to_draw2 + 1),store_text_x,store_text_y, hdc);
on_what_line++;
MoveTo(dest_rect.left + 1 , dest_rect.top + 1 + line_height * on_what_line + 9);
last_line_break = last_word_break;
if (force_skip == TRUE) {
force_skip = FALSE;
i++;
last_line_break++;
last_word_break++;
}
if ((start_of_last_kept_word >= last_line_break) && (current_rect > 0)) {
OffsetRect(&store_words[current_rect - 1].word_rect,5 + -1 * store_words[current_rect - 1].word_rect.left,line_height);
}
}
if (str[i] == ' ') { // New word
store_last_word_break = last_word_break = i + 1;
}
if (on_what_line == 17)
i = 10000;
}
}
SelectObject(hdc,store_bmp);
SelectObject(hdc,store_font);
if (!DeleteDC(hdc)) DebugQuit("Cannot release DC 7");
refresh_talking();
// Clean up strings
for (i = 0; i < 50; i++)
for (j = 0; j < 4; j++)
if ((store_words[current_rect].word[j] >= 65) && (store_words[current_rect].word[j] <= 90))
store_words[current_rect].word[j] += 32;
}
void refresh_talking()
{
RECT from = {0,0,279,415};
rect_draw_some_item(talk_gworld,from,talk_gworld,talk_area_rect,0,1);
}
short scan_for_response(char *str)
// returns -1 if no go
{
short i;
for (i = 0; i < 60; i++) { // 60 response in each bunch
if ((talking.talk_nodes[i].personality != -1) &&
((talking.talk_nodes[i].personality == store_personality)
|| (talking.talk_nodes[i].personality == -2)) &&
(((str[0] == talking.talk_nodes[i].link1[0]) && (str[1] == talking.talk_nodes[i].link1[1])
&& (str[2] == talking.talk_nodes[i].link1[2]) && (str[3] == talking.talk_nodes[i].link1[3]))
|| ((str[0] == talking.talk_nodes[i].link2[0]) && (str[1] == talking.talk_nodes[i].link2[1])
&& (str[2] == talking.talk_nodes[i].link2[2]) && (str[3] == talking.talk_nodes[i].link2[3]))))
return i;
}
return -1;
}