doubleclicks, old savegame ui

This commit is contained in:
Ondřej Novák 2025-03-01 19:53:54 +01:00
parent fed5a04323
commit 1e7bbcb245
12 changed files with 334 additions and 155 deletions

View file

@ -1,14 +1,14 @@
#define EX_RANDOM_BACKFIRES 1 //hotovo #define EX_RANDOM_BACKFIRES 1
#define EX_RESPAWN_MONSTERS 2 //hotovo #define EX_RESPAWN_MONSTERS 2
#define EX_SMART_ROGUE 4 #define EX_SMART_ROGUE 4 //canceled
#define EX_RECOVER_DESTROYED_ITEMS 8 //hotovo #define EX_RECOVER_DESTROYED_ITEMS 8
#define EX_MULTIPLE_ITEMS_IN_CURSOR 16 //zruseno #define EX_MULTIPLE_ITEMS_IN_CURSOR 16 //canceled
#define EX_BAG_EXTENDED 32 //hotovo #define EX_BAG_EXTENDED 32
#define EX_SHIELD_BLOCKING 64 #define EX_SHIELD_BLOCKING 64 //canceled
#define EX_FAST_TRADE 128 //hotovo #define EX_FAST_TRADE 128 //always enabled
#define EX_ALWAYS_MINIMAP 256 //hotovo #define EX_ALWAYS_MINIMAP 256
#define EX_GROUP_FLEE 512 #define EX_GROUP_FLEE 512 //canceled, but enabled on boat
#define EX_NOHUNGRY 1024 #define EX_NOHUNGRY 1024
#define EX_AUTOOPENBOOK 2048 #define EX_AUTOOPENBOOK 2048
#define EX_AUTOSHOWRUNE 4096 #define EX_AUTOSHOWRUNE 4096 //always enabled
extern int game_extras; extern int game_extras;

View file

@ -67,6 +67,7 @@ int hal_dir;
char see_monster=0; char see_monster=0;
char ghost_walls = 0; char ghost_walls = 0;
char lodka=0; char lodka=0;
char lodka_battle_draw = 0; //jedncka pokud se zobrazuje programovani (pro lodku)
int bgr_distance=0; //vzdalenost pozadi od pohledu int bgr_distance=0; //vzdalenost pozadi od pohledu
int bgr_handle=0; int bgr_handle=0;
@ -457,6 +458,7 @@ void bott_disp_text(const char *text)
strcpy(bott_text,text); strcpy(bott_text,text);
} }
/*
static void MaskPutPicture(int x, int y, char mask, word color, char blend, const void *pic) static void MaskPutPicture(int x, int y, char mask, word color, char blend, const void *pic)
{ {
short *info=(short *)pic; short *info=(short *)pic;
@ -474,33 +476,88 @@ static void MaskPutPicture(int x, int y, char mask, word color, char blend, cons
} }
} }
} }
*/
static void *extractByMask(const short *image, const short *mask_data, int mask) {
short left = 0x7FFF;
short right = 0;
short top = 0x7FFF;
short bottom =0;
short xs = image[0];
short mxs = mask_data[0];
short mys = mask_data[1];
const char *mdata = (const char *)mask_data+sizeof(short)*3+512;
for (short y = 0; y < mys; ++y) {
for (short x = 0; x < mxs; ++x) {
if (mdata[y*mxs+x] == mask) {
if (left > x) left = x;
if (right < x) right = x;
if (bottom < y) bottom = y;
if (top > y) top = y;
}
}
}
if (left > right || top > bottom) return NULL;
short nxs = right-left+1;
short nys = bottom-top+1;
short *newimg = getmem(nxs*nys*2+3+256);
newimg[0] = nxs;
newimg[1] = nys;
newimg[2] = image[2];
memcpy(newimg+2, image+2, sizeof(short)*266);
char *imgdata = (char *)(newimg+3+256);
const char *srcimgdata = (char *)(image+3+256);
for (short y = top; y <= bottom; ++y) {
for (short x = left; x <= right; ++x) {
char color = 0;
if (mdata[y*mxs+x] == mask) {
color = srcimgdata[y*xs+x];
} else {
color = 0;
}
imgdata[(y - top)*nxs+(x - left)] = color;
}
}
return newimg;
}
const void *bott_draw_rune(const void *pp, int32_t *ss) const void *bott_draw_rune(const void *pp, int32_t *ss)
{ {
int sel_zivel=showrune/10; int sel_zivel=showrune/10;
int sel_rune=showrune%10; int sel_rune=showrune%10;
int maskrune=runes[sel_zivel]; // int maskrune=runes[sel_zivel];
int i; // int i;
char buff[300]; char buff[300];
int spell=(sel_zivel*7+sel_rune)*3; int spell=(sel_zivel*7+sel_rune)*3;
RedirectScreen(bott_clear()); RedirectScreen(bott_clear());
if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR));
else put_picture(0,0,ablock(H_DESK)); else put_picture(0,0,ablock(H_DESK));
create_frame(70,20,280,50,1);
put_picture(378,0,ablock(H_RUNEBAR1+sel_zivel)); short *rn = extractByMask(ablock(H_RUNEBAR1+sel_zivel),
ablock(H_RUNEMASK), sel_rune+6);
/*
put_picture(520,0,);
for (i=0;i<7;i++) for (i=0;i<7;i++)
if (!(maskrune & (1<<i))) MaskPutPicture(378,0,i+6,0,0,ablock(H_RUNEMASK)); if (!(maskrune & (1<<i))) MaskPutPicture(520,0,i+6,0,0,ablock(H_RUNEMASK));
else if (i!=sel_rune) MaskPutPicture(378,0,i+6,0,1,ablock(H_RUNEMASK)); else if (i!=sel_rune) MaskPutPicture(520,0,i+6,0,1,ablock(H_RUNEMASK));
if (sel_zivel) trans_bar(378,0,sel_zivel*24,22,0); if (sel_zivel) trans_bar(520,0,sel_zivel*24,22,0);
if (sel_zivel!=4)trans_bar(378+24+sel_zivel*24,0,96-sel_zivel*24,22,0); if (sel_zivel!=4)trans_bar(520+24+sel_zivel*24,0,96-sel_zivel*24,22,0);
*/
create_frame(70,20,400,50,1);
set_font(H_FBOLD,NOSHADOW(0)); set_font(H_FBOLD,NOSHADOW(0));
position(120,30); position(120,30);
outtext(glob_items[showruneitem].jmeno); outtext(glob_items[showruneitem].jmeno);
sprintf(buff,"%s %d, %s %d",texty[11],get_spell_um(spell),texty[16],get_spell_mana(spell)); sprintf(buff,"%s %d, %s %d",texty[11],get_spell_um(spell),texty[16],get_spell_mana(spell));
position (75,60); position (120,60);
outtext(buff); outtext(buff);
put_picture(70,30,ablock(glob_items[showruneitem].vzhled+face_arr[0])); if (rn) {
put_picture(80,35,rn);
free(rn);
}
void *out = GetScreenAdr(); void *out = GetScreenAdr();
*ss=GetScreenSizeBytes(); *ss=GetScreenSizeBytes();
RestoreScreen(); RestoreScreen();
@ -1264,14 +1321,16 @@ void render_scene(int sector, int smer)
} }
calc_spectxtrs(); calc_spectxtrs();
if (lodka) { if (lodka) {
if (cur_mode == MD_GAME) { if (!lodka_battle_draw && !running_anm) {
if (!lodka_loaded) { if (!lodka_loaded) {
game_display_load_sprite(H_LODKA, (const unsigned short *)ablock(H_LODKA)); game_display_load_sprite(H_LODKA, (const unsigned short *)ablock(H_LODKA));
lodka_loaded = 1; lodka_loaded = 1;
} }
game_display_place_sprite(H_LODKA, 0, SCREEN_OFFLINE+301); game_display_place_sprite(H_LODKA, 0, SCREEN_OFFLINE+301);
} else { } else {
game_display_hide_sprite(H_LODKA);
zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ); zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ);
lodka_battle_draw = 0;
} }
} }
} }

View file

@ -738,15 +738,30 @@ static char view_another_click2(int id,int xa,int ya,int xr,int yr)
return 0; return 0;
} }
static void wait_timer(EVENT_MSG *msg, void **udata) {
if (msg->msg == E_TIMER) {
exit_wait = 1;
}
}
void effect_show(va_list args) void effect_show(va_list args)
{ {
int i; int i;
char s = exit_wait;
schovej_mysku(); schovej_mysku();
for(i=0;i<12;i++) for(i=0;i<12;i++)
{ {
showview(0,240-i*20-20,640,20); showview(0,240-i*20-20,640,20);
showview(0,240+(i*20),640,20); showview(0,240+(i*20),640,20);
task_wait_event(E_TIMER); if (q_current_task() != -1) {
task_wait_event(E_TIMER);
} else {
send_message(E_ADD, E_TIMER, wait_timer);
escape();
exit_wait = s;
send_message(E_DONE, E_TIMER, wait_timer);
}
} }
ukaz_mysku(); ukaz_mysku();
} }

View file

@ -339,12 +339,7 @@ char clk_saveload(int id,int xa,int ya,int xr,int yr)
if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc(); if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc();
unwire_proc(); unwire_proc();
cancel_render=1; cancel_render=1;
if (id == 1) { wire_save_load(id);
do_save_dialog();
wire_proc();
} else {
wire_save_load(id);
}
return 1; return 1;
} }

View file

@ -31,7 +31,7 @@
#define GM_MAPENABLE 0x1 #define GM_MAPENABLE 0x1
#define SAVE_SLOT_S 32 #define SAVE_SLOT_S 34
#define LOAD_SLOT_S (372+34) #define LOAD_SLOT_S (372+34)
#define SAVE_SLOT_E (34+203) #define SAVE_SLOT_E (34+203)
#define LOAD_SLOT_E (372+34+203) #define LOAD_SLOT_E (372+34+203)
@ -45,6 +45,8 @@ static long prev_game_time_save = -999;
static long play_time = 0; //current play time static long play_time = 0; //current play time
static long load_game_time = 0; //time when game has been loaded (to calculate play_time) static long load_game_time = 0; //time when game has been loaded (to calculate play_time)
#define AUTOSAVE_SUFFIX "-autosave"
char reset_mobiles=0; char reset_mobiles=0;
typedef struct s_save typedef struct s_save
@ -770,7 +772,7 @@ static int load_global_events()
return 0; return 0;
} }
int save_game(long game_time,char *gamename) int save_game(long game_time,char *gamename, char is_autosave)
{ {
char *gn; char *gn;
FILE *svf; FILE *svf;
@ -783,7 +785,7 @@ int save_game(long game_time,char *gamename)
} }
char str_buff[50]; char str_buff[50];
snprintf(str_buff,sizeof(str_buff),"sav.%08lx.%08lx", current_campaign, game_time); snprintf(str_buff,sizeof(str_buff),"sav.%08lx.%08lx%s", current_campaign, game_time, is_autosave?AUTOSAVE_SUFFIX:"");
SEND_LOG("(SAVELOAD) Saving game slot %d",game_time); SEND_LOG("(SAVELOAD) Saving game slot %d",game_time);
save_map_state(); save_map_state();
@ -1275,7 +1277,18 @@ static void read_story(const char *filename) {
TSTR_LIST ls; TSTR_LIST ls;
char *c,*d; char *c,*d;
load_specific_file(filename,STORY_BOOK,&text_data,&size); if (filename) {
load_specific_file(filename,STORY_BOOK,&text_data,&size);
} else {
int32_t sz = temp_storage_find(STORY_BOOK);
if (sz < 0) {
text_data = NULL;
} else {
text_data = getmem(sz);
temp_storage_retrieve(STORY_BOOK, text_data, sz);
size = sz;
}
}
if (text_data!=NULL) if (text_data!=NULL)
{ {
ls=create_list(2); ls=create_list(2);
@ -1498,7 +1511,7 @@ void save_step_next(EVENT_MSG *msg,void **unused)
if (c==13) if (c==13)
{ {
send_message(E_KEYBOARD,c); send_message(E_KEYBOARD,c);
save_game(slot_pos,global_gamename); save_game(slot_pos,global_gamename,0);
wire_proc(); wire_proc();
// read_slot_list(); // read_slot_list();
msg->msg=-2; msg->msg=-2;
@ -1531,7 +1544,7 @@ static void save_it(char ok)
{ {
if (ok) if (ok)
{ {
save_game(slot_pos,global_gamename); save_game(slot_pos,global_gamename,0);
// read_slot_list(); // read_slot_list();
wire_proc(); wire_proc();
GlobEvent(MAGLOB_AFTERSAVE,viewsector,viewdir); GlobEvent(MAGLOB_AFTERSAVE,viewsector,viewdir);
@ -1566,6 +1579,8 @@ void wire_ask_gamename(int id)
ukaz_mysku(); ukaz_mysku();
} }
static void save_as_dialog(int pos);
#define CLK_SAVELOAD 11 #define CLK_SAVELOAD 11
T_CLK_MAP clk_load[]= T_CLK_MAP clk_load[]=
@ -1591,8 +1606,7 @@ static char clk_save_proc(int id,int xa,int ya,int xr,int yr)
xa;ya;xr;yr; xa;ya;xr;yr;
if (ms_last_event.event_type & 0x2 && id>=0) if (ms_last_event.event_type & 0x2 && id>=0)
{ {
unwire_proc(); save_as_dialog(id);
wire_ask_gamename(id);
} }
return 1; return 1;
} }
@ -1618,7 +1632,7 @@ static void select_slot(int i) {
while (rel < 0) { while (rel < 0) {
--current_slot_list_top_line; --current_slot_list_top_line;
schovej_mysku(); schovej_mysku();
redraw_load(); if (force_save) redraw_save(); else redraw_load();
showview(0,0,0,0); showview(0,0,0,0);
ukaz_mysku(); ukaz_mysku();
rel++; rel++;
@ -1626,14 +1640,15 @@ static void select_slot(int i) {
while (rel > SLOTS_MAX-1) { while (rel > SLOTS_MAX-1) {
++current_slot_list_top_line; ++current_slot_list_top_line;
schovej_mysku(); schovej_mysku();
redraw_load(); if (force_save) redraw_save(); else redraw_load();
showview(0,0,0,0); showview(0,0,0,0);
ukaz_mysku(); ukaz_mysku();
rel--; rel--;
} }
int m = force_save != 0?1:0;
if (last_select != i) { if (last_select != i) {
if (last_select != -1) place_name(0,last_select-current_slot_list_top_line,1,0); if (last_select != -1) place_name(m,last_select-current_slot_list_top_line,1,0);
place_name(0,i-current_slot_list_top_line,1,1); place_name(m,i-current_slot_list_top_line,1,1);
last_select = i; last_select = i;
if (last_select != -1 && last_select < (int)current_game_slot_list.count) { if (last_select != -1 && last_select < (int)current_game_slot_list.count) {
read_story(current_game_slot_list.files[last_select]); read_story(current_game_slot_list.files[last_select]);
@ -1649,9 +1664,17 @@ static void saveload_keyboard(EVENT_MSG *msg,void **_)
switch (v>>8) switch (v>>8)
{ {
case 1:unwire_proc();wire_proc();break; case 1:unwire_proc();wire_proc();break;
case 17:
case 'H':if (last_select>0) select_slot(last_select-1);break; case 'H':if (last_select>0) select_slot(last_select-1);break;
case 31:
case 'P':if (last_select<(int)current_game_slot_list.count-1) select_slot(last_select+1);break; case 'P':if (last_select<(int)current_game_slot_list.count-1) select_slot(last_select+1);break;
case 28:if (last_select>=0) load_save_pos_ingame(last_select);break; case 28:if (last_select>=0) {
if (force_save) {
save_as_dialog(last_select);
} else {
load_save_pos_ingame(last_select);break;
}
}
} }
} }
} }
@ -1664,11 +1687,13 @@ static void saveload_keyboard_menu(EVENT_MSG *msg,void **_)
switch (v>>8) switch (v>>8)
{ {
case 1:send_message(E_CLOSE_MAP,NULL);break; case 1:send_message(E_CLOSE_MAP,NULL);break;
case 17:
case 'H':if (last_select>0) select_slot(last_select-1);break; case 'H':if (last_select>0) select_slot(last_select-1);break;
case 31:
case 'P':if (last_select<(int)current_game_slot_list.count-1) select_slot(last_select+1);break; case 'P':if (last_select<(int)current_game_slot_list.count-1) select_slot(last_select+1);break;
case 28:if (last_select>= 0 && last_select < (int)current_game_slot_list.count) { case 28:if (last_select>= 0 && last_select < (int)current_game_slot_list.count) {
send_message(E_CLOSE_MAP, current_game_slot_list.files[last_select]); send_message(E_CLOSE_MAP, current_game_slot_list.files[last_select]);
break; break;
} }
} }
@ -1688,29 +1713,29 @@ void unwire_save_load(void)
free_savegame_list(&current_game_slot_list); free_savegame_list(&current_game_slot_list);
} }
void wire_save_load(char save) {
if (save == 1) {
//TODO save
} else {
schovej_mysku();
mute_all_tracks(0);
current_game_slot_list = get_all_savegames(current_campaign);
void wire_save_load(char save) {
schovej_mysku();
mute_all_tracks(0);
force_save=save & 1;
current_game_slot_list = get_all_savegames(current_campaign);
curcolor = RGB555(0,0,0);
bar32(0, 17, 639, 17 + 360);
if (save == 1) {
current_game_slot_list.count++;
str_insline(&current_game_slot_list.files, 0, NULL);
str_insline(&current_game_slot_list.names, 0, texty[75]);
change_click_map(clk_save,CLK_SAVELOAD);
redraw_save();
send_message(E_ADD, E_KEYBOARD, saveload_keyboard);
effect_show(NULL);
} else {
curcolor = 0; curcolor = 0;
bar32(0, 17, 639, 17 + 360); redraw_load();
if (force_save) effect_show(NULL);
redraw_save(); if (save == 2)
else
redraw_load();
if (save == 4)
effect_show(NULL);
else
showview(0, 0, 0, 0);
redraw_story_bar(cur_story_pos);
unwire_proc = unwire_save_load;
if (save == 1)
change_click_map(clk_save, CLK_SAVELOAD);
else if (save == 2)
change_click_map(clk_load_error, CLK_LOAD_ERROR); change_click_map(clk_load_error, CLK_LOAD_ERROR);
else if (save == 4) { else if (save == 4) {
change_click_map(clk_load_menu, CLK_LOAD_MENU); change_click_map(clk_load_menu, CLK_LOAD_MENU);
@ -1720,15 +1745,17 @@ void wire_save_load(char save) {
send_message(E_ADD, E_KEYBOARD, saveload_keyboard); send_message(E_ADD, E_KEYBOARD, saveload_keyboard);
change_click_map(clk_load, CLK_SAVELOAD); change_click_map(clk_load, CLK_SAVELOAD);
} }
cancel_pass = 1;
if (last_select != -1) {
int x = last_select * SLOT_SPACE + 1;
last_select = -1;
bright_slot(x);
}
ukaz_mysku();
update_mysky();
} }
redraw_story_bar(cur_story_pos);
cancel_pass = 1;
if (last_select != -1) {
int x = last_select * SLOT_SPACE + 1;
last_select = -1;
bright_slot(x);
}
ukaz_mysku();
update_mysky();
unwire_proc = unwire_save_load;
} }
@ -1808,7 +1835,7 @@ int load_map_automap(char *mapfile)
#define DEFAULT_GAME_NAME(extra) \ #define DEFAULT_GAME_NAME(extra) \
char game_name[100];\ char game_name[100];\
long cur_time = get_game_tick_count()/1000;\ long cur_time = get_game_tick_count()/1000;\
long game_time = play_time + get_game_tick_count()/1000 - load_game_time;\ long game_time = play_time + cur_time/1000 - load_game_time;\
if (game_time < 60) snprintf(game_name, sizeof(game_name), "%s" extra, mglob.mapname);\ if (game_time < 60) snprintf(game_name, sizeof(game_name), "%s" extra, mglob.mapname);\
else snprintf(game_name, sizeof(game_name), "%s %02lu:%02lu" extra, mglob.mapname, game_time/3600, (game_time/60)%60); else snprintf(game_name, sizeof(game_name), "%s %02lu:%02lu" extra, mglob.mapname, game_time/3600, (game_time/60)%60);
@ -1820,18 +1847,53 @@ long get_save_game_slot_id() {
void do_autosave() { void do_autosave() {
DEFAULT_GAME_NAME(" (A)"); DEFAULT_GAME_NAME(" (A)");
if (cur_time - prev_game_time_save<300) return; //autosave is no more often than each 5 minutes char prefix[50];
prev_game_time_save = cur_time; snprintf(prefix,50,"sav.%08lx.",current_campaign);
save_game(get_save_game_slot_id(), game_name); TSAVEGAME_CB_STATE st;
st.files = create_list(32);
st.prefix = prefix;
st.prefix_len = strlen(prefix);
st.count = 0;
list_files(gpathtable[SR_SAVES], file_type_just_name|file_type_need_timestamp|file_type_normal, get_all_savegames_callback, &st);
for (size_t i = 0; i < st.count; ++i) {
const char *n = st.files[i];
if (strstr(n, AUTOSAVE_SUFFIX)) {
remove(build_pathname(2, gpathtable[SR_SAVES],n));
}
}
save_game(get_save_game_slot_id(), game_name,1);
} }
void do_save_dialog() { void do_save_dialog() {
/*
DEFAULT_GAME_NAME(""); DEFAULT_GAME_NAME("");
if (ask_save_dialog(game_name, sizeof(game_name))) { if (ask_save_dialog(game_name, sizeof(game_name))) {
prev_game_time_save = cur_time; prev_game_time_save = cur_time;
save_game(get_save_game_slot_id(), game_name); save_game(get_save_game_slot_id(), game_name);
} }
*/
} }
static void save_as_dialog(int pos) {
DEFAULT_GAME_NAME("");
const char *todel = current_game_slot_list.files[pos];
const char *name = current_game_slot_list.names[pos];
if (todel != NULL) {
strcopy_n(game_name, name, sizeof(game_name));
todel = build_pathname(2,gpathtable[SR_SAVES],todel);
todel = local_strdup(todel);
}
unwire_proc();
if (ask_save_dialog(game_name, sizeof(game_name))) {
prev_game_time_save = cur_time;
save_game(get_save_game_slot_id(), game_name,0);
if (todel) {
remove(todel);
}
wire_proc();
return;
}
wire_save_load(1);
}

View file

@ -611,6 +611,7 @@ extern char enable_sort;
extern char last_send_action; //naposled vyslana akce extern char last_send_action; //naposled vyslana akce
extern char see_monster; //jednicka pokud hraci vidi nestvuru extern char see_monster; //jednicka pokud hraci vidi nestvuru
extern char lodka; extern char lodka;
extern char lodka_battle_draw; //jedncka pokud se zobrazuje programovani (pro lodku)
extern char anim_mirror; //je li 1 pak animace kouzel a zbrani jsou zrcadlove otocene extern char anim_mirror; //je li 1 pak animace kouzel a zbrani jsou zrcadlove otocene
extern char insleep; //je li 1 pak bezi sleep extern char insleep; //je li 1 pak bezi sleep
extern char pass_zavora; //je-li 1 pak bezi passing (hraci zrovna jdou) extern char pass_zavora; //je-li 1 pak bezi passing (hraci zrovna jdou)
@ -1404,7 +1405,7 @@ int save_map_state(void); //uklada stav mapy pro savegame (neuklada aktualni poz
int load_map_state(void); //obnovuje stav mapy; nutno volat po zavolani load_map; int load_map_state(void); //obnovuje stav mapy; nutno volat po zavolani load_map;
void restore_current_map(void); //pouze obnovuje ulozeny stav aktualni mapy void restore_current_map(void); //pouze obnovuje ulozeny stav aktualni mapy
int load_game(const char *fname); int load_game(const char *fname);
int save_game(long game_time,char *gamename); int save_game(long game_time,char *gamename, char is_autosave);
void wire_save_load(char save); void wire_save_load(char save);
void do_save_dialog(); void do_save_dialog();
char ask_save_dialog(char *name_buffer, size_t name_size); char ask_save_dialog(char *name_buffer, size_t name_size);

View file

@ -581,7 +581,7 @@ void do_items_specs(void)
runes[xa]|=ya; runes[xa]|=ya;
destroy=1; destroy=1;
play_fx_at(FX_MAGIC); play_fx_at(FX_MAGIC);
if (game_extras & EX_AUTOSHOWRUNE) bott_disp_rune(p->user_value,*picked_item-1); bott_disp_rune(p->user_value,*picked_item-1);
break; break;
case TYP_PENIZE: case TYP_PENIZE:
{ {
@ -812,7 +812,7 @@ T_CLK_MAP clk_inv_view[]=
{1,236,220,255,239,ring_place,2,-1}, {1,236,220,255,239,ring_place,2,-1},
{2,236,255,255,274,ring_place,2,-1}, {2,236,255,255,274,ring_place,2,-1},
{3,236,290,255,309,ring_place,2,-1}, {3,236,290,255,309,ring_place,2,-1},
{0,0,200,29,309,uloz_sip,2,-1}, {0,0,200,29,309,uloz_sip,MS_EVENT_MOUSE_LPRESS|MS_EVENT_MOUSE_LDBLCLK,-1},
{-1,37,34,225,336,human_click,2,-1}, {-1,37,34,225,336,human_click,2,-1},
{-1,45,339,212,358,inv_swap_desk,2,H_MS_DEFAULT}, {-1,45,339,212,358,inv_swap_desk,2,H_MS_DEFAULT},
{-1,54,378,497,479,start_invetory,2+8,-1}, {-1,54,378,497,479,start_invetory,2+8,-1},
@ -1762,16 +1762,33 @@ char uloz_sip(int id,int xa,int ya,int xr,int yr)
if (isdemon(human_selected)) return 0; if (isdemon(human_selected)) return 0;
if (neprezbrojit()) return 0; if (neprezbrojit()) return 0;
if (picked_item!=NULL && picked_item[1]==0 && glob_items[picked_item[0]-1].umisteni==PL_SIP) if (picked_item!=NULL && picked_item[1]==0 && glob_items[picked_item[0]-1].umisteni==PL_SIP) {
{ char notdblclk = !(ms_last_event.event_type & MS_EVENT_MOUSE_LDBLCLK);
int pocet=glob_items[picked_item[0]-1].user_value; if (notdblclk) {
if (pocet==0) pocet=1; int pocet=glob_items[picked_item[0]-1].user_value;
if (human_selected->sipy+pocet>99) return 1; if (pocet==0) pocet=1;
human_selected->sipy+=pocet; if (human_selected->sipy+pocet>99) return 1;
free(picked_item); human_selected->sipy+=pocet;
picked_item=NULL; free(picked_item);
picked_item=NULL;
} else if (glob_items[picked_item[0]-1].user_value <= 1) {
int best_item = -1;
int max_arrows = 1;
for (int i = 0; i < item_count; ++i) {
if (glob_items[i].umisteni == PL_SIP
&& glob_items[i].user_value > max_arrows
&& glob_items[i].user_value <= human_selected->sipy+1) {
max_arrows = glob_items[i].user_value;
best_item = i;
}
}
if (best_item>=0) {
picked_item[0] = best_item+1;
human_selected->sipy-=max_arrows-1;
}
} }
else
} else
if (picked_item==NULL && human_selected->sipy) if (picked_item==NULL && human_selected->sipy)
{ {
short x[2]; short x[2];
@ -2393,10 +2410,10 @@ T_CLK_MAP clk_shop[]=
{ {
{-1,54,378,497,479,shop_change_player,2+8,-1}, {-1,54,378,497,479,shop_change_player,2+8,-1},
{-1,0,0,639,479,_exit_shop,8,-1}, {-1,0,0,639,479,_exit_shop,8,-1},
{-1,INV_X,INV_Y,INV_X+INV_XS*6,INV_Y+INV_YS*5,shop_bag_click,2,-1}, {-1,INV_X,INV_Y,INV_X+INV_XS*6,INV_Y+INV_YS*5,shop_bag_click,MS_EVENT_MOUSE_LDBLCLK|MS_EVENT_MOUSE_LPRESS,-1},
{1,2+BUYBOX_X,39+BUYBOX_Y,22+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT}, {1,2+BUYBOX_X,39+BUYBOX_Y,22+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT},
{2,246+BUYBOX_X,39+BUYBOX_Y,266+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT}, {2,246+BUYBOX_X,39+BUYBOX_Y,266+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT},
{-1,BUYBOX_X+SHP_ICPLCX,17,BUYBOX_X+SHP_ICPLCX+4*SHP_ICSIZX,BUYBOX_Y+SHP_ICPLCY+2*SHP_ICSIZY,shop_keeper_click,2,-1}, {-1,BUYBOX_X+SHP_ICPLCX,17,BUYBOX_X+SHP_ICPLCX+4*SHP_ICSIZX,BUYBOX_Y+SHP_ICPLCY+2*SHP_ICSIZY,shop_keeper_click,MS_EVENT_MOUSE_LDBLCLK|MS_EVENT_MOUSE_LPRESS,-1},
{-1,0,17,BUYBOX_X+SHP_ICPLCX,BUYBOX_Y,shop_keeper_click,2,-1}, {-1,0,17,BUYBOX_X+SHP_ICPLCX,BUYBOX_Y,shop_keeper_click,2,-1},
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, {-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
{-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT},
@ -2791,16 +2808,31 @@ char shop_keeper_click(int id, int xa, int ya, int xr, int yr) {
return 1; return 1;
} }
} else if (cur_owner == -1) { } else if (cur_owner == -1) {
free(picked_item); char notdblclk = !(ms_last_event.event_type & MS_EVENT_MOUSE_LDBLCLK);
picked_item = NULL; if (notdblclk || get_sell_price(*picked_item) > money) {
rebuild_keepers_items(); free(picked_item);
schovej_mysku(); picked_item = NULL;
pick_set_cursor(); rebuild_keepers_items();
redraw_keepers_items(); schovej_mysku();
ukaz_mysku(); pick_set_cursor();
update_mysky(); redraw_keepers_items();
cur_owner = 0; ukaz_mysku();
return 1; update_mysky();
cur_owner = 0;
return 1;
} else {
play_sample_at_channel(H_SND_OBCHOD, 1, 100);
money -= get_sell_price(*picked_item);
sell_item(*picked_item);
if (put_item_to_inv(human_selected, picked_item)) {
picked_item = NULL;
pick_set_cursor();
}
rebuild_keepers_items();
cur_owner = picked_item != NULL;
redraw_shop();
return 1;
}
} }
if (cur_owner != -1 && picked_item != NULL) { if (cur_owner != -1 && picked_item != NULL) {
int price, z; int price, z;
@ -2860,52 +2892,54 @@ char shop_keeper_click(int id, int xa, int ya, int xr, int yr) {
} }
char shop_bag_click(int id,int xa,int ya,int xr,int yr) char shop_bag_click(int id, int xa, int ya, int xr, int yr) {
{ char s[200], p;
char s[200],p; int price, z;
int price,z; const TPRODUCT *pp;
const TPRODUCT *pp; if (cur_owner > -1) {
if (cur_owner>-1) char notdblclk = !(ms_last_event.event_type & MS_EVENT_MOUSE_LDBLCLK);
{ if (notdblclk) {
id=bag_click(id,xa,ya,xr,yr); id = bag_click(id, xa, ya, xr, yr);
cur_owner=picked_item!=NULL; } else {
if (picked_item!=NULL && picked_item[1]==0 && (game_extras & EX_FAST_TRADE) && (get_control_key_state())) id = 1;
{ }
short z; cur_owner = picked_item != NULL;
price=make_offer(z=picked_item[0]); if (picked_item != NULL && picked_item[1] == 0 && !notdblclk) {
if (price) short z;
{ price = make_offer(z = picked_item[0]);
play_sample_at_channel(H_SND_OBCHOD,1,100); if (price) {
buy_item(z); play_sample_at_channel(H_SND_OBCHOD, 1, 100);
free(picked_item);picked_item=NULL; buy_item(z);
money+=price; free(picked_item);
rebuild_keepers_items(); picked_item = NULL;
pick_set_cursor(); money += price;
redraw_shop(); rebuild_keepers_items();
} pick_set_cursor();
} redraw_shop();
return id; }
} }
if (picked_item==NULL) return 0; return id;
z=picked_item[0]; }
price=get_sell_price(z); if (picked_item == NULL) return 0;
pp=find_sell_product(z); z = picked_item[0];
if (pp==NULL) return 0; price = get_sell_price(z);
mouse_set_cursor(H_MS_DEFAULT); pp = find_sell_product(z);
if (!price) return 0; if (pp == NULL) return 0;
mouse_set_cursor(H_MS_DEFAULT);
if (!price) return 0;
if (price > money) { if (price > money) {
p = message(2, 0, 0, "", texty[104], texty[230], texty[78])+1; p = message(2, 0, 0, "", texty[104], texty[230], texty[78]) + 1;
} else { } else {
sprintf(s, texty[101], price); sprintf(s, texty[101], price);
p = message(3, 0, 1, texty[118], s, texty[77], texty[230], texty[78]); p = message(3, 0, 1, texty[118], s, texty[77], texty[230], texty[78]);
} }
if (p == 1) { if (p == 1) {
redraw_shop(); redraw_shop();
THAGGLERESULT hr = smlouvat_dlg(price, pp->cena, THAGGLERESULT hr = smlouvat_dlg(price, pp->cena, *get_product_count(pp),
*get_product_count(pp), *get_last_haggle_price(pp), money, 1); *get_last_haggle_price(pp), money, 1);
if (hr.canceled) { if (hr.canceled) {
price = -1; price = -1;
}else if (hr.message) { } else if (hr.message) {
price = -1; price = -1;
shop_keeper_bubble = hr.message; shop_keeper_bubble = hr.message;
*get_last_haggle_price(pp) = hr.hprice; *get_last_haggle_price(pp) = hr.hprice;
@ -2915,22 +2949,19 @@ char shop_bag_click(int id,int xa,int ya,int xr,int yr)
} else if (p == 2) { } else if (p == 2) {
price = -1; price = -1;
} }
if (price>=0) if (price >= 0) {
{ play_sample_at_channel(H_SND_OBCHOD, 1, 100);
play_sample_at_channel(H_SND_OBCHOD,1,100); money -= price;
money-=price;
sell_item(z); sell_item(z);
rebuild_keepers_items(); rebuild_keepers_items();
id=bag_click(id,xa,ya,xr,yr); id = bag_click(id, xa, ya, xr, yr);
cur_owner=picked_item!=NULL; cur_owner = picked_item != NULL;
} } else {
else shop_keeper_click(0, 0, 0, 0, 0);
{
shop_keeper_click(0,0,0,0,0);
} }
wire_shop(); wire_shop();
return 1; return 1;
} }
char shop_block_click(int id, int xa, int ya,int xr,int yr) char shop_block_click(int id, int xa, int ya,int xr,int yr)
{ {

View file

@ -1956,6 +1956,7 @@ void game_keyboard(EVENT_MSG *msg,void **usr)
case 1:konec(0,0,0,0,0);break; case 1:konec(0,0,0,0,0);break;
// case 25:GamePause();break; // case 25:GamePause();break;
case 28:enforce_start_battle();break; case 28:enforce_start_battle();break;
case 63:do_autosave();break;
case 45: case 45:
case 82:group_all();break; case 82:group_all();break;
case '<':if (!battle && GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir)) case '<':if (!battle && GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir))

View file

@ -1758,6 +1758,8 @@ void program_draw()
int x=54+74/2; int x=54+74/2;
int i,j,maxy=0; int i,j,maxy=0;
lodka_battle_draw = 1;
maxy; maxy;
schovej_mysku(); schovej_mysku();
if (group_flee) { if (group_flee) {

View file

@ -6,6 +6,16 @@ extern "C" {
#ifndef __SKELDAL__MOUSE__ #ifndef __SKELDAL__MOUSE__
#define __SKELDAL__MOUSE__ #define __SKELDAL__MOUSE__
#define MS_EVENT_MOUSE_MOVE 1
#define MS_EVENT_MOUSE_LPRESS 2
#define MS_EVENT_MOUSE_LRELEASE 4
#define MS_EVENT_MOUSE_RPRESS 8
#define MS_EVENT_MOUSE_RRELEASE 16
#define MS_EVENT_MOUSE_MPRESS 32
#define MS_EVENT_MOUSE_MRELEASE 64
#define MS_EVENT_MOUSE_LDBLCLK 128
typedef struct ms_event typedef struct ms_event
{ {
char event; char event;

View file

@ -21,7 +21,7 @@
#define CASE_FALLTHROUGH #define CASE_FALLTHROUGH
//microsoft doesn't support VLA //microsoft doesn't support VLA
#define DECL_VLA(type, variable, count) type *variable = (type *)alloca((count)*sizeof(type)); #define DECL_VLA(type, variable, count) type *variable = (type *)alloca((count)*sizeof(type));
#define GET_VLA_SIZE(variable, count) ((count)*sizeof(*variable)) #define GET_VLA_SIZE(variable, count) ((count)*sizeof(*variable))
#else #else

View file

@ -313,6 +313,9 @@ void SDLContext::event_loop(std::stop_token stp) {
case 3: ms_event.tl2 = !up; shift = 3; break; case 3: ms_event.tl2 = !up; shift = 3; break;
} }
ms_event.event_type |= (1<<(shift+up)); ms_event.event_type |= (1<<(shift+up));
if (e.type == SDL_MOUSEBUTTONDOWN && e.button.clicks == 2 && e.button.button == 1) {
ms_event.event_type |= MS_EVENT_MOUSE_LDBLCLK;
}
} }
} }
@ -573,7 +576,7 @@ void SDLContext::update_zindex() {
} }
template<typename T> template<typename T>
requires(std::is_trivially_copy_constructible_v<T>) requires(std::is_trivially_copy_constructible_v<T>)
void SDLContext::push_item(const T &item) { void SDLContext::push_item(const T &item) {
auto b = reinterpret_cast<const char *>(&item); auto b = reinterpret_cast<const char *>(&item);
auto e = b + sizeof(T); auto e = b + sizeof(T);
auto sz = _display_update_queue.size(); auto sz = _display_update_queue.size();