several fixes and improvements (combat log) - windows

This commit is contained in:
Ondrej Novak 2025-02-11 11:04:30 +01:00
parent 05726326bd
commit 2d7697174d
15 changed files with 332 additions and 158 deletions

View file

@ -1273,7 +1273,7 @@ void death_screen() {
int ys; int ys;
int y = 160; int y = 160;
const char *t = texty[65]; const char *t = texty[65];
char buff[strlen(t)+4]; DECL_VLA(char, buff, strlen(t)+4);
set_font(H_FBOLD, RGB555_ALPHA(31,31,31)); set_font(H_FBOLD, RGB555_ALPHA(31,31,31));
zalamovani(t,buff, 440, &xs, &ys); zalamovani(t,buff, 440, &xs, &ys);
t = buff; t = buff;

View file

@ -136,7 +136,7 @@ char clk_touch(int id,int xa,int ya,int xr,int yr)
return 0; return 0;
} }
char clk_fly_cursor(int id,int xa,int ya,int xr,int yr) static char clk_fly_cursor(int id,int xa,int ya,int xr,int yr)
{ {
id; id;

View file

@ -4,7 +4,7 @@
#include <ctype.h> #include <ctype.h>
#define console_max_characters 120 #define console_max_characters 120
#define console_max_lines 16 #define console_max_lines 300
void macro_drop_item(int sector,int smer,short item); void macro_drop_item(int sector,int smer,short item);
/****/ /****/
@ -371,21 +371,22 @@ extern char pass_all_mobs;
static char console_input_line[console_max_characters+1] = ""; static char console_input_line[console_max_characters+1] = "";
static char *console_output_lines[console_max_lines] = {}; static char *console_output_lines[console_max_lines] = {};
static int console_top_line = 0;
static const int console_x = 0; static const int console_x = 0;
static const int console_y = 20; static const int console_y = SCREEN_OFFLINE;
static const int console_width = 640; static const int console_width = 640;
static const int console_height = 160; static const int console_height = 165;
static const int console_padding = 3; static const int console_padding = 3;
static int console_blink = 0; static int console_blink = 0;
static char console_visible = 0; static char console_visible = 0;
#define CONSOLE_FONT H_FTINY
void draw_console_window() { void draw_console_window() {
if (!console_visible) return; if (!console_visible) return;
trans_bar(console_x, console_y, console_width, console_height, 0); trans_bar(console_x, console_y, console_width, console_height, 0);
set_font(H_FLITT5, RGB888(255,255,128)); set_font(CONSOLE_FONT, RGB555(31,31,16));
int y = console_y+console_height-text_height("X")-console_padding; int y = console_y+console_height-text_height("X")-console_padding;
position(console_x+console_padding, y); position(console_x+console_padding, y);
outtext("$ "); outtext("$ ");
@ -395,14 +396,16 @@ void draw_console_window() {
} }
++console_blink; ++console_blink;
set_font(H_FLITT5, RGB888(255,255,255)); set_font(CONSOLE_FONT, RGB555(31,31,31));
y-=3*text_height("X")/2; y-=3*text_height("X")/2;
for (int i = 0; i < console_max_lines;++i) { for (int i = 0; i < console_max_lines;++i) {
int p = i + console_top_line;
if (p>=console_max_lines) break;
position(console_x+console_padding,y); position(console_x+console_padding,y);
if (console_output_lines[i]) outtext(console_output_lines[i]); if (console_output_lines[p]) outtext(console_output_lines[p]);
y-=text_height("X"); y-=text_height("X");
if (y < console_y+console_padding) break; if (y < console_y+console_padding) break;
} }
@ -416,6 +419,7 @@ static void console_add_line(const char *line) {
free(console_output_lines[console_max_lines-1]); free(console_output_lines[console_max_lines-1]);
memmove(console_output_lines+1,console_output_lines, (console_max_lines-1)*sizeof(char *)); memmove(console_output_lines+1,console_output_lines, (console_max_lines-1)*sizeof(char *));
console_output_lines[0] = strdup(line); console_output_lines[0] = strdup(line);
} }
typedef struct { typedef struct {
@ -755,7 +759,8 @@ static int process_command(PARSED_COMMAND cmd) {
static void console_keyboard(EVENT_MSG *msg, void **_) { static void console_keyboard(EVENT_MSG *msg, void **_) {
if (msg->msg == E_KEYBOARD) { if (msg->msg == E_KEYBOARD) {
int c = va_arg(msg->data, int) & 0xFF; int code = va_arg(msg->data, int);
int c = code & 0xFF;
if (c == E_QUIT_GAME_KEY) return; if (c == E_QUIT_GAME_KEY) return;
if (c) { if (c) {
int len = strlen(console_input_line); int len = strlen(console_input_line);
@ -774,6 +779,7 @@ static void console_keyboard(EVENT_MSG *msg, void **_) {
char ok = process_command(cmd); char ok = process_command(cmd);
if (ok) { if (ok) {
console_add_line(console_input_line); console_add_line(console_input_line);
console_top_line = 0;
console_input_line[0] = 0; console_input_line[0] = 0;
} }
free(cmd.cmd_buffer); free(cmd.cmd_buffer);
@ -783,6 +789,17 @@ static void console_keyboard(EVENT_MSG *msg, void **_) {
console_input_line[len+1] = 0; console_input_line[len+1] = 0;
msg->msg = -1; msg->msg = -1;
} }
} else {
switch (code >> 8) {
case 'I': console_top_line = MIN(console_max_lines-10, console_top_line+10);break;
case 'Q': console_top_line = MAX(0, console_top_line-10);break;
case 'H': console_top_line = MIN(console_max_lines-10, console_top_line+1);break;
case 'P': console_top_line = MAX(0, console_top_line-1);break;
case 'G': console_top_line = console_max_characters-10;
case 'O': console_top_line = 0;
default: return;
}
msg->msg = -1;
} }
} }
} }

View file

@ -1449,7 +1449,12 @@ void mob_strelba(TMOB *p)
t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL]; t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL];
spell_throw(-((p-mobs)+1),i); spell_throw(-((p-mobs)+1),i);
letici_veci->flags &=~FLY_DESTROY; letici_veci->flags &=~FLY_DESTROY;
letici_veci->hit_bonus=p->vlastnosti[VLS_UTOK_L]+rnd(p->vlastnosti[VLS_UTOK_H]-p->vlastnosti[VLS_UTOK_L]+1); int att = p->vlastnosti[VLS_OBRAT]/5;
letici_veci->hit_bonus=p->vlastnosti[VLS_UTOK_L]+rnd(p->vlastnosti[VLS_UTOK_H]-p->vlastnosti[VLS_UTOK_L]+1) + att;
if (log_combat) {
wzprintf("%s shoots: %d (roll %d-%d) + %d (%s/5) = %d\n",
p->vlastnosti[VLS_UTOK_L],p->vlastnosti[VLS_UTOK_H],att,texty[13],letici_veci->hit_bonus);
}
letici_veci->damage=p->vlastnosti[VLS_DAMAGE]; letici_veci->damage=p->vlastnosti[VLS_DAMAGE];
p->dostal=0; p->dostal=0;
} }
@ -1556,12 +1561,13 @@ void mobs_hit(TMOB *p)
spec=vlastnosti[VLS_KOUZLA]; spec=vlastnosti[VLS_KOUZLA];
if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(h,vlastnosti); if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(h,vlastnosti);
else uprav_podle_kondice(h,&pocet); else uprav_podle_kondice(h,&pocet);
h->dostal=vypocet_zasahu(p->vlastnosti,vlastnosti,pocet,0,0); //vypocet zasahu h->dostal=vypocet_zasahu(p->vlastnosti,vlastnosti,pocet,0,0,1); //vypocet zasahu
if (h->dostal) p->dostal=0; if (h->dostal) p->dostal=0;
if (spec & SPL_OKO) //oko za oko pro hrace if (spec & SPL_OKO) //oko za oko pro hrace
{ {
vybrana_zbran=-1; vybrana_zbran=-1;
mob_hit(p,h->dostal); mob_hit(p,h->dostal);
if (log_combat) wzprintf("%s was hit (eye for an eye): %d\n", p->name, h->dostal);
mob_check_death(p-mobs,p); mob_check_death(p-mobs,p);
} }
if (h->dostal && p->vlastnosti[VLS_KOUZLA] & SPL_KNOCK) knock_player_back(h,p->dir); if (h->dostal && p->vlastnosti[VLS_KOUZLA] & SPL_KNOCK) knock_player_back(h,p->dir);
@ -1569,6 +1575,7 @@ void mobs_hit(TMOB *p)
{ {
p->lives+=h->dostal; p->lives+=h->dostal;
if (p->lives>p->vlastnosti[VLS_MAXHIT])p->lives=p->vlastnosti[VLS_MAXHIT]; if (p->lives>p->vlastnosti[VLS_MAXHIT])p->lives=p->vlastnosti[VLS_MAXHIT];
if (log_combat) wzprintf("%s drained HP : %d, lives %d\n", p->name, h->dostal, p->lives);
} }
dead=player_hit(h,h->dostal,1); dead=player_hit(h,h->dostal,1);
if (h->lives>h->vlastnosti[VLS_MAXHIT]) h->lives=h->vlastnosti[VLS_MAXHIT]; if (h->lives>h->vlastnosti[VLS_MAXHIT]) h->lives=h->vlastnosti[VLS_MAXHIT];
@ -2169,11 +2176,31 @@ static void knock_mob_back(TMOB *mm,int dir)
recheck_button(sek,1); recheck_button(sek,1);
} }
int utok_na_sektor(THUMAN *p,TMOB *mm,int ch,int bonus) static void remove_other_weapon_from_calc(THUMAN *p, short *vlastnosti, int poz) {
int otherpoz = poz == PO_RUKA_L?PO_RUKA_R:PO_RUKA_L;
int itnum = p->wearing[otherpoz];
if (itnum == 0) return;
const TITEM *it = glob_items + itnum-1;
if (it->druh != TYP_UTOC) return;
int vls[] = {VLS_MGSIL_H,VLS_MGSIL_L,VLS_UTOK_H,VLS_UTOK_L,VLS_DAMAGE};
for (int i = 0; i < countof(vls); ++i) {
vlastnosti[vls[i]] -= it->zmeny[vls[i]];
}
}
int utok_na_sektor(THUMAN *p,TMOB *mm,int ch,int bonus, int ruka)
{ {
int dostal; int dostal;
short vlastnosti[VLS_MAX];
const short *use_vls = p->vlastnosti;
dostal=vypocet_zasahu(p->vlastnosti,mm->vlastnosti,ch,bonus,0); if (ruka == PO_RUKA_L || ruka == PO_RUKA_R) {
memcpy(vlastnosti, p->vlastnosti, sizeof(vlastnosti));
remove_other_weapon_from_calc(p, vlastnosti, ruka);
use_vls = vlastnosti;
}
dostal=vypocet_zasahu(use_vls,mm->vlastnosti,ch,bonus,0,ruka != PL_OBOUR);
mob_hit(mm,dostal); mob_hit(mm,dostal);
if (dostal && p->vlastnosti[VLS_KOUZLA] & SPL_KNOCK) knock_mob_back(mm,p->direction); if (dostal && p->vlastnosti[VLS_KOUZLA] & SPL_KNOCK) knock_mob_back(mm,p->direction);
if (mm->vlastnosti[VLS_KOUZLA] & SPL_OKO) //oko za oko pro potvoru if (mm->vlastnosti[VLS_KOUZLA] & SPL_OKO) //oko za oko pro potvoru

View file

@ -41,6 +41,8 @@
static TMPFILE_WR *story=NULL; static TMPFILE_WR *story=NULL;
static char load_another; static char load_another;
static unsigned long current_campaign = 0; static unsigned long current_campaign = 0;
static long prev_game_time_save = 0;
char reset_mobiles=0; char reset_mobiles=0;
typedef struct s_save typedef struct s_save
@ -749,7 +751,7 @@ static int load_global_events()
return 0; return 0;
} }
int save_game(int game_time,char *gamename, char skip_if_exists) int save_game(int game_time,char *gamename)
{ {
char *gn; char *gn;
FILE *svf; FILE *svf;
@ -762,17 +764,13 @@ int save_game(int game_time,char *gamename, char skip_if_exists)
} }
char str_buff[50]; char str_buff[50];
snprintf(str_buff,sizeof(str_buff),"sav.%010lx.%08X", current_campaign, game_time); snprintf(str_buff,sizeof(str_buff),"sav.%08lx.%08X", current_campaign, game_time);
SEND_LOG("(SAVELOAD) Saving game slot %d",game_time); SEND_LOG("(SAVELOAD) Saving game slot %d",game_time);
save_map_state(); save_map_state();
const char *sn = build_pathname(2,gpathtable[SR_SAVES],str_buff); const char *sn = build_pathname(2,gpathtable[SR_SAVES],str_buff);
sn = local_strdup(sn); sn = local_strdup(sn);
if (skip_if_exists && check_file_exists(sn)) {
SEND_LOG("(SAVELOAD) Save skipped - already exists");
return 0;
}
create_directories(gpathtable[SR_SAVES]); create_directories(gpathtable[SR_SAVES]);
gn=alloca(SAVE_NAME_SIZE); gn=alloca(SAVE_NAME_SIZE);
strcopy_n(gn,gamename,SAVE_NAME_SIZE); strcopy_n(gn,gamename,SAVE_NAME_SIZE);
@ -807,7 +805,7 @@ int load_game(const char *fname)
FILE *svf; FILE *svf;
int r,t; int r,t;
sscanf(fname,"sav.%lx", &current_campaign); sscanf(fname,"sav.%lx.%lx", &current_campaign, &prev_game_time_save);
SEND_LOG("(SAVELOAD) Loading file: %s",fname); SEND_LOG("(SAVELOAD) Loading file: %s",fname);
if (battle) konec_kola(); if (battle) konec_kola();
@ -881,7 +879,7 @@ static char load_mode;
#define SLOT_SPACE 33 #define SLOT_SPACE 33
#define SLOT_FONT H_FBOLD #define SLOT_FONT H_FBOLD
#define SELECT_COLOR RGB555(31,31,31) #define SELECT_COLOR RGB555(31,31,31)
#define NORMAL_COLOR RGB555(20,31,20) #define NORMAL_COLOR RGB555(12,31,12)
#define STORY_X 57 #define STORY_X 57
#define STORY_Y 50 #define STORY_Y 50
#define STORY_XS (298-57) #define STORY_XS (298-57)
@ -924,6 +922,7 @@ typedef struct {
} TSAVEGAME_LIST; } TSAVEGAME_LIST;
static TSAVEGAME_LIST current_game_slot_list = {}; static TSAVEGAME_LIST current_game_slot_list = {};
static int current_slot_list_top_line = 0;
typedef struct { typedef struct {
TSTR_LIST files; TSTR_LIST files;
@ -941,13 +940,23 @@ static char is_same_prefix(const char *name, const char *prev_name) {
return 0; return 0;
} }
static int get_all_savegames_callback(const char *name, LIST_FILE_TYPE type , size_t size, void *ctx) { static int get_all_savegames_callback(const char *name, LIST_FILE_TYPE type , size_t tm, void *ctx) {
if (istrncmp(name, "sav.", 4) != 0 if (istrncmp(name, "sav.", 4) != 0
&& istrcmp(name+strlen(name)-4,".sav") != 0) && istrcmp(name+strlen(name)-4,".sav") != 0)
return 0; return 0;
TSAVEGAME_CB_STATE *st = (TSAVEGAME_CB_STATE *)ctx; TSAVEGAME_CB_STATE *st = (TSAVEGAME_CB_STATE *)ctx;
if (st->prefix_len == 0 || strncmp(name, st->prefix, st->prefix_len) == 0) { if (st->prefix_len == 0 || strncmp(name, st->prefix, st->prefix_len) == 0) {
str_replace(&(st->files), st->count, name); size_t nlen = strlen(name);
if (st->count == (size_t)str_count(st->files)) {
TSTR_LIST nw = create_list(st->count * 3/2);
str_move_list(nw, st->files);;
release_list(st->files);
st->files = nw;
}
char *buff = NewArr(char, nlen + 1 + sizeof(tm));
strncpy(buff, name, nlen+1);
memcpy(buff+nlen+1, &tm, sizeof(tm));
st->files[st->count] = buff;
++st->count; ++st->count;
} }
return 0; return 0;
@ -957,6 +966,16 @@ static int compare_strings (const void *a, const void *b) {
return strcmp(*(const char **)a, *(const char **)b); return strcmp(*(const char **)a, *(const char **)b);
} }
static int compare_by_time (const void *a, const void *b) {
const char *s1 = *(const char **)a;
const char *s2 = *(const char **)b;
size_t tm1;
size_t tm2;
memcpy(&tm1, s1 + strlen(s1)+1, sizeof(tm1));
memcpy(&tm2, s2 + strlen(s2)+1, sizeof(tm2));
return tm1<tm2?1:tm1>tm2?-1:0;
}
static int dedup_strings_prefix(TSTR_LIST lst, int count) { static int dedup_strings_prefix(TSTR_LIST lst, int count) {
int j = -1; int j = -1;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
@ -1008,27 +1027,22 @@ static void load_specific_file(int slot_num,char *filename,void **out,int32_t *s
static TSAVEGAME_LIST get_all_savegames(unsigned long kampan) { static TSAVEGAME_LIST get_all_savegames(unsigned long kampan) {
//sav.creation_time.game_save_time //sav.creation_time.game_save_time
char prefix[50]; char prefix[50];
snprintf(prefix,50,"sav.%010lx.",kampan); snprintf(prefix,50,"sav.%08lx.",kampan);
TSAVEGAME_CB_STATE st; TSAVEGAME_CB_STATE st;
st.files = create_list(32); st.files = create_list(32);
st.prefix = kampan?prefix:NULL; st.prefix = kampan?prefix:NULL;
st.prefix_len = kampan?strlen(prefix):0; st.prefix_len = kampan?strlen(prefix):0;
st.count = 0; st.count = 0;
list_files(gpathtable[SR_SAVES], file_type_just_name|file_type_normal, get_all_savegames_callback, &st); list_files(gpathtable[SR_SAVES], file_type_just_name|file_type_need_timestamp|file_type_normal, get_all_savegames_callback, &st);
qsort(st.files, st.count, sizeof(char *), compare_strings); qsort(st.files, st.count, sizeof(char *), compare_strings);
if (kampan == 0) { if (kampan == 0) {
st.count =dedup_strings_prefix(st.files, (int)st.count); st.count =dedup_strings_prefix(st.files, (int)st.count);
} }
TSTR_LIST files = create_list(st.count); qsort(st.files, st.count, sizeof(char *), compare_by_time);
for (size_t i = 0; i < st.count; ++i) {
files[st.count-i-1] = st.files[i];
st.files[i] = NULL;
}
release_list(st.files);
TSTR_LIST names = create_list(st.count); TSTR_LIST names = create_list(st.count);
for (size_t i = 0; i < st.count; ++i) { for (size_t i = 0; i < st.count; ++i) {
FILE *f=fopen_icase(build_pathname(2, gpathtable[SR_SAVES], files[i]), "rb"); FILE *f=fopen_icase(build_pathname(2, gpathtable[SR_SAVES], st.files[i]), "rb");
if (f!=NULL) { if (f!=NULL) {
char slotname[SAVE_NAME_SIZE+1]; char slotname[SAVE_NAME_SIZE+1];
fread(slotname,1,SAVE_NAME_SIZE,f); fread(slotname,1,SAVE_NAME_SIZE,f);
@ -1041,7 +1055,7 @@ static TSAVEGAME_LIST get_all_savegames(unsigned long kampan) {
} }
TSAVEGAME_LIST out; TSAVEGAME_LIST out;
out.files = files; out.files = st.files;
out.names = names; out.names = names;
out.count = st.count; out.count = st.count;
return out; return out;
@ -1057,10 +1071,11 @@ static void free_savegame_list(TSAVEGAME_LIST *lst) {
static void place_name(int c,int i,char show, char sel) static void place_name(int c,int i,char show, char sel)
{ {
int z,x; int z,x;
if ((size_t)i >= current_game_slot_list.count) return; int p = i + current_slot_list_top_line;
if ((size_t)p >= current_game_slot_list.count) return;
if (c) x=SAVE_SLOT_S;else x=LOAD_SLOT_S; if (c) x=SAVE_SLOT_S;else x=LOAD_SLOT_S;
if (show) schovej_mysku(); if (show) schovej_mysku();
const char *name = current_game_slot_list.names[i]; const char *name = current_game_slot_list.names[p];
set_font(SLOT_FONT,sel?SELECT_COLOR:NORMAL_COLOR); set_font(SLOT_FONT,sel?SELECT_COLOR:NORMAL_COLOR);
int w = text_width(name); int w = text_width(name);
int spc = 0; int spc = 0;
@ -1199,23 +1214,14 @@ static int get_list_count()
return max-20; return max-20;
} }
static void select_slot(int i);
static int bright_slot(int yr) static int bright_slot(int yr)
{ {
int id; int id;
id=yr/SLOT_SPACE; id=yr/SLOT_SPACE+current_slot_list_top_line;
if ((yr % SLOT_SPACE)<18 && yr>0) select_slot(id);
{
if (id!=last_select)
{
if (last_select!=-1) place_name(force_save,last_select,1,0);
place_name(force_save,id,1,1);
last_select=id;
read_story(id);
}
}
else
id=-1;
return id; return id;
} }
@ -1307,12 +1313,14 @@ T_CLK_MAP clk_load_error[]=
}; };
static char clk_load_proc_menu(int id,int xa,int ya,int xr,int yr) static char clk_load_proc_menu(int id,int xa,int ya,int xr,int yr)
{ {
id=bright_slot(yr-18); id=bright_slot(yr-18);
xa;ya;xr;yr; xa;ya;xr;yr;
if (ms_last_event.event_type & 0x2 && id>=0 && (size_t)id < current_game_slot_list.count) if (ms_last_event.event_type & 0x2 && id>=0 && (size_t)id < current_game_slot_list.count) {
send_message(E_CLOSE_MAP,current_game_slot_list.files[id]); send_message(E_CLOSE_MAP,current_game_slot_list.files[id]);
}
return 1; return 1;
} }
@ -1326,38 +1334,43 @@ T_CLK_MAP clk_load_menu[]=
{-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT},
}; };
static void load_save_pos_ingame(int id) {
if (load_game(current_game_slot_list.files[id]))
{
message(1,0,0,"",texty[79],texty[80]);
redraw_load();
showview(0,0,0,0);
change_click_map(clk_load_error,CLK_LOAD_ERROR);
}
else
{
unwire_proc();
wire_proc();
if (battle) konec_kola();
unwire_proc();
if (!load_another)
{
wire_main_functs();
cur_mode=MD_GAME;
bott_draw(1);
pick_set_cursor();
for(id=0;id<mapsize;id++) map_coord[id].flags&=~MC_DPLAYER;
build_player_map();
}
reg_grafiku_postav();
build_all_players();
cancel_render=1;
}
}
static char clk_load_proc(int id,int xa,int ya,int xr,int yr) static char clk_load_proc(int id,int xa,int ya,int xr,int yr)
{ {
id=bright_slot(yr-18); id=bright_slot(yr-18);
xa;ya;xr;yr; xa;ya;xr;yr;
if (ms_last_event.event_type & 0x2 && id>=0 && (size_t)id < current_game_slot_list.count) if (ms_last_event.event_type & 0x2 && id>=0 && (size_t)id < current_game_slot_list.count)
{ {
if (load_game(current_game_slot_list.files[id])) load_save_pos_ingame(id);
{
message(1,0,0,"",texty[79],texty[80]);
redraw_load();
showview(0,0,0,0);
change_click_map(clk_load_error,CLK_LOAD_ERROR);
}
else
{
unwire_proc();
wire_proc();
if (battle) konec_kola();
unwire_proc();
if (!load_another)
{
wire_main_functs();
cur_mode=MD_GAME;
bott_draw(1);
pick_set_cursor();
for(id=0;id<mapsize;id++) map_coord[id].flags&=~MC_DPLAYER;
build_player_map();
}
reg_grafiku_postav();
build_all_players();
cancel_render=1;
}
} }
return 1; return 1;
} }
@ -1376,7 +1389,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,1); save_game(slot_pos,global_gamename);
wire_proc(); wire_proc();
// read_slot_list(); // read_slot_list();
msg->msg=-2; msg->msg=-2;
@ -1409,7 +1422,7 @@ static void save_it(char ok)
{ {
if (ok) if (ok)
{ {
save_game(slot_pos,global_gamename,1); save_game(slot_pos,global_gamename);
// read_slot_list(); // read_slot_list();
wire_proc(); wire_proc();
GlobEvent(MAGLOB_AFTERSAVE,viewsector,viewdir); GlobEvent(MAGLOB_AFTERSAVE,viewsector,viewdir);
@ -1465,7 +1478,7 @@ T_CLK_MAP clk_load[]=
static char clk_save_proc(int id,int xa,int ya,int xr,int yr) static char clk_save_proc(int id,int xa,int ya,int xr,int yr)
{ {
id=bright_slot(yr-18); id=bright_slot(yr-18)+current_slot_list_top_line;
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)
{ {
@ -1491,6 +1504,32 @@ T_CLK_MAP clk_save[]=
{-1,0,0,639,479,close_saveload,9,H_MS_DEFAULT}, {-1,0,0,639,479,close_saveload,9,H_MS_DEFAULT},
}; };
static void select_slot(int i) {
int rel = i-current_slot_list_top_line;
char unbright = 1;
while (rel < 0) {
--current_slot_list_top_line;
schovej_mysku();
redraw_load();
showview(0,0,0,0);
ukaz_mysku();
rel++;
unbright = 0;
}
while (rel > SLOTS_MAX-1) {
++current_slot_list_top_line;
schovej_mysku();
redraw_load();
showview(0,0,0,0);
ukaz_mysku();
unbright = 0;
rel--;
}
if (last_select != -1) place_name(0,last_select-current_slot_list_top_line,1,0);
place_name(0,i-current_slot_list_top_line,1,1);
last_select = i;
}
static void saveload_keyboard(EVENT_MSG *msg,void **_) static void saveload_keyboard(EVENT_MSG *msg,void **_)
{ {
if (msg->msg == E_KEYBOARD) if (msg->msg == E_KEYBOARD)
@ -1499,15 +1538,9 @@ 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 'H':if (last_select>0) bright_slot((last_select-1)*SLOT_SPACE+1);break; case 'H':if (last_select>0) select_slot(last_select-1);break;
case 'P':if (last_select<SLOTS_MAX-1) bright_slot((last_select+1)*SLOT_SPACE+1);break; case 'P':if (last_select<current_game_slot_list.count-1) select_slot(last_select+1);break;
case 28:ms_last_event.event_type|=0x2; case 28:if (last_select>=0) load_save_pos_ingame(last_select);break;
if (force_save) clk_save_proc(0,0,0,0,last_select*SLOT_SPACE+1+18);
else if (load_mode==4)
clk_load_proc_menu(0,0,0,0,last_select*SLOT_SPACE+1+18);
else
clk_load_proc(0,0,0,0,last_select*SLOT_SPACE+1+18);
break;
} }
} }
} }
@ -1520,17 +1553,15 @@ 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 'H':if (last_select>0) bright_slot((last_select-1)*SLOT_SPACE+1);break; case 'H':if (last_select>0) select_slot(last_select-1);break;
case 'P':if (last_select<SLOTS_MAX-1) bright_slot((last_select+1)*SLOT_SPACE+1);break; case 'P':if (last_select<current_game_slot_list.count-1) select_slot(last_select+1);break;
case 28:ms_last_event.event_type|=0x2; case 28:if (last_select>= 0 && last_select < current_game_slot_list.count) {
if (force_save) clk_save_proc(0,0,0,0,last_select*SLOT_SPACE+1+18); send_message(E_CLOSE_MAP, current_game_slot_list.files[last_select]);
else if (load_mode==4) break;
clk_load_proc_menu(0,0,0,0,last_select*SLOT_SPACE+1+18);
else
clk_load_proc(0,0,0,0,last_select*SLOT_SPACE+1+18);
break;
} }
} }
}
} }
void unwire_save_load(void) void unwire_save_load(void)
@ -1662,23 +1693,36 @@ int load_map_automap(char *mapfile)
return load_map_state_partial(mapfile,mapsize); //nahrej ulozenou mapu return load_map_state_partial(mapfile,mapsize); //nahrej ulozenou mapu
} }
static void herni_cas_for_savegame(char *c) {
int32_t inmin = game_time/6;
if (inmin >= 96*60) {
int32_t inhours = inmin/60;
sprintf(c,"%dd %dh", inhours/24, inhours%24);
} else {
sprintf(c,"%02d:%02d", inmin/60, inmin%60);
}
}
#define DEFAULT_GAME_NAME(extra) \ #define DEFAULT_GAME_NAME(extra) \
char game_name[100];\ char game_name[100];\
char hernicas[50];\ char hernicas[50];\
herni_cas(hernicas);\ herni_cas_for_savegame(hernicas);\
snprintf(game_name, sizeof(game_name), "%s %s" extra, mglob.mapname, hernicas); snprintf(game_name, sizeof(game_name), "%s %s" extra, mglob.mapname, hernicas);
void do_autosave() { void do_autosave() {
DEFAULT_GAME_NAME(" (A)"); DEFAULT_GAME_NAME(" (A)");
save_game(game_time, game_name,1); if (game_time - prev_game_time_save<360) return;
prev_game_time_save = game_time;
save_game(game_time, game_name);
} }
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))) {
save_game(game_time, game_name, 0); prev_game_time_save = game_time;
save_game(game_time, game_name);
} }

View file

@ -1404,7 +1404,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(int game_time,char *gamename, char skip_if_exists); int save_game(int game_time,char *gamename);
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);
@ -1547,7 +1547,7 @@ void check_all_mobs_battle(void); //kontroluje zda je nekdo v battle
void manashield_check(short *vls,short *lives,short *mana,int dostal); void manashield_check(short *vls,short *lives,short *mana,int dostal);
char track_mob(int sect,int dir);//trackuje pritomnost potvory v urcitem smeru char track_mob(int sect,int dir);//trackuje pritomnost potvory v urcitem smeru
void stop_all_mobs(void); void stop_all_mobs(void);
int utok_na_sektor(THUMAN *p,TMOB *m,int chaos,int bonus); int utok_na_sektor(THUMAN *p,TMOB *m,int chaos,int bonus, int ruka);
int vyber_potvoru(int sect,int dir,int *chaos); //vybere potvoru ze sektoru a smeru. Vraci take pocet potvor v promenne *chaos int vyber_potvoru(int sect,int dir,int *chaos); //vybere potvoru ze sektoru a smeru. Vraci take pocet potvor v promenne *chaos
void load_enemies(short *data,int size,int *grptr,TMOB *template,int32_t tsize); void load_enemies(short *data,int size,int *grptr,TMOB *template,int32_t tsize);
char mob_test_na_bitvu(TMOB *p); //nastavi p->vlajky|MOB_INBATTLE pokud potvora muze vstoupit do bitvy; char mob_test_na_bitvu(TMOB *p); //nastavi p->vlajky|MOB_INBATTLE pokud potvora muze vstoupit do bitvy;
@ -1572,7 +1572,7 @@ void zacni_souboj(TMOB *p,int delka,short sector);
char q_zacit_souboj(TMOB *p,int d,short sector); char q_zacit_souboj(TMOB *p,int d,short sector);
void stop_mob(TMOB *p); void stop_mob(TMOB *p);
void start_battle(void); void start_battle(void);
int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int bonusplus); int vypocet_zasahu(const short *utocnik,const short *obrance, int chaos,int zbran,int bonusplus, char enable_finesse_rule);
void rozhodni_o_smeru(TMOB *p); void rozhodni_o_smeru(TMOB *p);
void krok_moba(TMOB *p); void krok_moba(TMOB *p);
void pomala_regenerace_postavy(THUMAN *p); void pomala_regenerace_postavy(THUMAN *p);

View file

@ -484,7 +484,7 @@ static char load_index_map(int index)
*/ */
if (!GlobEvent(MAGLOB_LEAVEMAP,viewsector,viewdir)) return 0; if (!GlobEvent(MAGLOB_LEAVEMAP,viewsector,viewdir)) return 0;
viewsector=lv; viewsector=lv;
strcopy_n(x.name,index_tab[index].mapname,12); strcopy_n(x.name,index_tab[index].mapname,sizeof(x.name));
x.start_pos=0; x.start_pos=0;
x.dir=0; x.dir=0;
macro_load_another_map(&x); macro_load_another_map(&x);

View file

@ -853,7 +853,7 @@ void prepocitat_postavu(THUMAN *human_selected)
} }
p=sr1+VLS_DAMAGE; //vypocet damage (bez omezeni) p=sr1+VLS_DAMAGE; //vypocet damage (bez omezeni)
q=&glob_items[c-1].zmeny[VLS_DAMAGE]; q=&glob_items[c-1].zmeny[VLS_DAMAGE];
*(p++)+=*q++; *(p++)+=*q++;
p=sr1+VLS_KOUZLA; //aplikace kouzel p=sr1+VLS_KOUZLA; //aplikace kouzel
q=&glob_items[c-1].zmeny[VLS_KOUZLA]; q=&glob_items[c-1].zmeny[VLS_KOUZLA];
(*p++)|=*q++; (*p++)|=*q++;
@ -1357,8 +1357,7 @@ static T_INV_SCRIPT script[]=
{0,37,NULL,0,97,1,0}, {0,37,NULL,0,97,1,0},
{30,5,"%d-%d",pvls(VLS_UTOK_L),pvls(VLS_UTOK_H),2,2}, {30,5,"%d-%d",pvls(VLS_UTOK_L),pvls(VLS_UTOK_H),2,2},
{30,7,"%d-%d",pvls(VLS_OBRAN_L),pvls(VLS_OBRAN_H),2,2}, {30,7,"%d-%d",pvls(VLS_OBRAN_L),pvls(VLS_OBRAN_H),2,2},
{28,9,"%d",INFO_AP,0,2,2}, {30,9,"%d",INFO_AP,0,2,2},
{28,9,".%d",INFO_APF,0,2,0},
{17,5,NULL,0,18,1,0}, {17,5,NULL,0,18,1,0},
{17,7,NULL,0,17,1,0}, {17,7,NULL,0,17,1,0},
{17,9,NULL,0,20,1,0}, {17,9,NULL,0,20,1,0},
@ -2055,7 +2054,7 @@ static char check_double_wield() {
if (!i1 || !i2) return 0; if (!i1 || !i2) return 0;
const TITEM *it1 = glob_items+i1; const TITEM *it1 = glob_items+i1;
const TITEM *it2 = glob_items+i2; const TITEM *it2 = glob_items+i2;
if (it1->typ_zbrane!=TYP_UTOC || it2->typ_zbrane!=TYP_UTOC ) return 0; if (it1->druh!=TYP_UTOC || it2->druh!=TYP_UTOC ) return 0;
for (int i = VLS_SILA; i <=VLS_OBRAT; ++i) { for (int i = VLS_SILA; i <=VLS_OBRAT; ++i) {
if ((it1->podminky[i] + it2->podminky[i] > human_selected->vlastnosti[i]) if ((it1->podminky[i] + it2->podminky[i] > human_selected->vlastnosti[i])
&& (MAX(it1->podminky[i], it2->podminky[i]) > human_selected->vlastnosti[VLS_OBRAT])) { && (MAX(it1->podminky[i], it2->podminky[i]) > human_selected->vlastnosti[VLS_OBRAT])) {

View file

@ -409,7 +409,7 @@ static void hit_1_player(int postava,const TMA_WOUND *w,int chaos)
memset(vls,0,sizeof(vls)); memset(vls,0,sizeof(vls));
vls[VLS_UTOK_L]=w->minor; vls[VLS_UTOK_L]=w->minor;
vls[VLS_UTOK_H]=w->major; vls[VLS_UTOK_H]=w->major;
dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0); dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0,0);
} }
else else
{ {
@ -419,7 +419,7 @@ static void hit_1_player(int postava,const TMA_WOUND *w,int chaos)
vls[VLS_MGSIL_L]=w->minor; vls[VLS_MGSIL_L]=w->minor;
vls[VLS_MGSIL_H]=w->major; vls[VLS_MGSIL_H]=w->major;
vls[VLS_MGZIVEL]=zivel; vls[VLS_MGZIVEL]=zivel;
dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0); dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0,0);
} }
player_hit(h,dostal,0); player_hit(h,dostal,0);
} }

View file

@ -1335,7 +1335,7 @@ char chod_s_postavama(char sekupit)
{ {
postavy[i].sektor=viewsector; postavy[i].sektor=viewsector;
postavy[i].direction=viewdir; postavy[i].direction=viewdir;
postavy[i].utek=1; postavy[i].utek=0;
postavy[i].kondice-=weigth_defect(postavy+i); postavy[i].kondice-=weigth_defect(postavy+i);
if (postavy[i].kondice<0) postavy[i].kondice=0; if (postavy[i].kondice<0) postavy[i].kondice=0;
group_nums[cur_group]=1; group_nums[cur_group]=1;

View file

@ -108,6 +108,8 @@ static char ask_who_proc(int id,int xa,int ya,int xr,int yr);
void wire_programming(); void wire_programming();
void souboje_vybrano(int d); void souboje_vybrano(int d);
void program_draw(); void program_draw();
static void souboje_turn(int smer);
static char clk_fly_cursor(int id,int xa,int ya,int xr,int yr);
void (*after_spell_wire)(); void (*after_spell_wire)();
@ -126,7 +128,7 @@ HUM_ACTION *magic_data;
static int minwait=0,maxwait=-1; static int minwait=0,maxwait=-1;
#define CLK_SOUBOJE 15 #define CLK_SOUBOJE 16
T_CLK_MAP clk_souboje[]= T_CLK_MAP clk_souboje[]=
{ {
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, {-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
@ -143,6 +145,7 @@ T_CLK_MAP clk_souboje[]=
{-1,528,378,630,479,mask_click_help,1,-1}, {-1,528,378,630,479,mask_click_help,1,-1},
{-1,0,0,640,480,mask_click_help_clear,1,-1}, {-1,0,0,640,480,mask_click_help_clear,1,-1},
{MS_GAME_WIN,0,17,639,377,souboje_clk_throw,2,-1}, {MS_GAME_WIN,0,17,639,377,souboje_clk_throw,2,-1},
{MS_GAME_WIN,0,17,639,377,clk_fly_cursor,8,-1},
{-1,54,378,497,479,start_invetory,2+8,-1}, {-1,54,378,497,479,start_invetory,2+8,-1},
}; };
@ -350,17 +353,21 @@ void zacni_souboj(TMOB *p,int d,short sector)
int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int external_force) int vypocet_zasahu(const short *utocnik,const short *obrance, int chaos,int zbran,int external_force, char enable_finesse_rule)
{ {
int zasah,mutok,flg; int zasah,mutok,flg;
flg=obrance[VLS_KOUZLA]; flg=obrance[VLS_KOUZLA];
short attack_attribute = MAX(utocnik[VLS_SILA], utocnik[VLS_OBRAT]); short attbonus = enable_finesse_rule?MAX(utocnik[VLS_SILA], utocnik[VLS_OBRAT]):utocnik[VLS_SILA];
char finesse = utocnik[VLS_SILA] != attbonus;
attbonus/=5;
int utok,obrana; int utok,obrana;
int ospod; int ospod;
int attack_roll,defense_roll,mag_att_roll,mg_def; int attack_roll,defense_roll,mag_att_roll,mg_def;
int dmzhit = 0; int dmzhit = 0;
int ddostal = 0; int ddostal = 0;
int disadv = 0; int disadv = 0;
int obrbonus = obrance[VLS_OBRAT]/5;
int magbonus = utocnik[VLS_SMAGIE]/5;
/* /*
if (game_extras & EX_ALTERNATEFIGHT) if (game_extras & EX_ALTERNATEFIGHT)
{ {
@ -398,11 +405,11 @@ int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int exter
mag_att_roll=utocnik[VLS_MGSIL_L]+rnd(utocnik[VLS_MGSIL_H]-utocnik[VLS_MGSIL_L]+1); mag_att_roll=utocnik[VLS_MGSIL_L]+rnd(utocnik[VLS_MGSIL_H]-utocnik[VLS_MGSIL_L]+1);
//hit=attack_roll+max(str,dex)+external_force //hit=attack_roll+max(str,dex)+external_force
utok=attack_roll+attack_attribute/5+external_force; utok=attack_roll+attbonus+external_force;
//def=defense_roll+dex/5+(10 if invisible) //def=defense_roll+dex/5+(10 if invisible)
obrana=defense_roll+(obrance[VLS_OBRAT]/5)+(flg & SPL_INVIS?10:0); obrana=defense_roll+obrbonus+(flg & SPL_INVIS?10:0);
//mg_attack = magic_roll //mg_attack = magic_roll
mutok=mag_att_roll+(mag_att_roll?(utocnik[VLS_SMAGIE]/5):0); mutok=mag_att_roll+(mag_att_roll?magbonus:0);
//mg_deffense (100-x) //mg_deffense (100-x)
mg_def=obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]]; mg_def=obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]];
//adjust magic attack //adjust magic attack
@ -411,44 +418,62 @@ int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int exter
} }
if (zasah<0) zasah=0; if (zasah<0) zasah=0;
int damage = utocnik[VLS_DAMAGE]+zbran; int damage = utocnik[VLS_DAMAGE]+zbran;
if (zasah<0 || damage<0) damage = 0; if (zasah<=0 || damage<=0) damage = 0;
ddostal=zasah; ddostal=zasah;
zasah+=damage; zasah+=damage;
if (log_combat) { if (log_combat) {
wzprintf("Combat: Attack roll (%d-%d) = %d, " wzprintf(">");
"Defense disadv.: %d*2/(%d+1)=%d , " if (utocnik[VLS_UTOK_H]) {
"Defense roll (%d-%d) = %d, " wzprintf("Attack (physical): %d (roll %d-%d) + %d (%s/5) + %d (ext.force) = %d\n",
"Magic roll (%d-%d) = %d\n", attack_roll, (int)utocnik[VLS_UTOK_L],(int)utocnik[VLS_UTOK_H],
(int)utocnik[VLS_UTOK_L],(int)utocnik[VLS_UTOK_H],attack_roll, attbonus, finesse?texty[13]:texty[10],
(int)obrance[VLS_OBRAN_L],chaos, ospod, external_force,utok);
ospod,(int)obrance[VLS_OBRAN_H], defense_roll, } else if (external_force) {
(int)utocnik[VLS_MGSIL_L],(int)utocnik[VLS_MGSIL_H], mag_att_roll); wzprintf("Attack (physical): %d (ext.force)\n", external_force);
wzprintf("Combat: phys.hit: %d(att.roll) + %d(%s)/5 +%d(ext.force) - %d(def.roll)-%d(%s)/5 + %d(damage)=%d(%d)\n", }
attack_roll, attack_attribute, if (obrance[VLS_OBRAN_H] && utok > 0) {
attack_attribute==utocnik[VLS_SILA]?texty[10]:texty[13], char chaos[50];
external_force, defense_roll, (int)obrance[VLS_OBRAT], if (disadv > 1) snprintf(chaos, 50, ", disadvantage %d", disadv);
texty[13], damage, utok-obrana, zasah); else strcpy(chaos,"");
if (mag_att_roll) { wzprintf(" Defense (physical): %d (roll %d-%d%s) + %d (%s/5) = %d\n",
wzprintf("Combat: %d(magic roll) + %d(%s)/5 = %d, magic resistance = %d(%s), magic hit: %d * (100 - %d)/100 = %d\n", defense_roll, ospod, obrance[VLS_OBRAN_H], chaos, obrbonus, texty[13], obrana);
mag_att_roll, (int)utocnik[VLS_SMAGIE], texty[11], mutok, mg_def,texty[22+utocnik[VLS_MGZIVEL]], mutok, mg_def, dmzhit); }
if (zasah>0) {
if (damage) {
wzprintf(" Psychical hit: %d - %d + %d (damage) + %d (weapon) = %d\n",
utok, obrana, utocnik[VLS_DAMAGE], zbran, zasah);
} else {
wzprintf(" Psychical hit: %d - %d = %d\n",
utok, obrana, zasah);
}
} }
} }
if (flg & SPL_SANC) { if (flg & SPL_SANC) {
zasah/=2; zasah/=2;
if (log_combat) wzprintf("Physical resistance applied: %d/2 = %d", ddostal, zasah); if (log_combat) wzprintf( "Physical resistance applied: %d - %d (half)= %d\n", ddostal,ddostal - zasah, zasah);
ddostal = zasah; ddostal = zasah;
} }
zasah=zasah+dmzhit; int total_hit = zasah+dmzhit;
if (log_combat) {
if ((int)utocnik[VLS_MGSIL_H]) {
wzprintf(" Attack (magical): %d (roll %d-%d) + %d (%s/5) = %d\n",
mag_att_roll,(int)utocnik[VLS_MGSIL_L],(int)utocnik[VLS_MGSIL_H], magbonus, texty[11], mutok);
wzprintf(" Magical hit: %d - %d (resistance %s: %d%%) = %d\n",
mutok, mutok - dmzhit, texty[22+utocnik[VLS_MGZIVEL]], mg_def, dmzhit);
wzprintf(" Total hit: %d (physical) + %d (magical) = %d\n",
zasah, dmzhit, total_hit);
}
}
if (flg & SPL_HSANC) { if (flg & SPL_HSANC) {
zasah/=2; int tmp = total_hit;
if (log_combat) wzprintf("Total resistance applied: %d/2 = %d", ddostal, zasah); total_hit/=2;
if (log_combat) wzprintf("Total resistance applied: %d - %d (half) = %d\n", tmp, total_hit - tmp);
} }
if (flg & SPL_TVAR) { if (flg & SPL_TVAR) {
if (log_combat) wzprintf("Set Face spell applied: %d = -%d (heal)", zasah, zasah); if (log_combat) wzprintf("Set Face spell applied: %d = -%d (heal)\n", total_hit, -total_hit);
zasah=-zasah; total_hit=-total_hit;
} }
return zasah; return total_hit;
} }
void rozhodni_o_poradi() void rozhodni_o_poradi()
@ -628,7 +653,7 @@ void zacatek_kola()
if (p->kondice && p->lives && p->inmaphash == current_map_hash) if (p->kondice && p->lives && p->inmaphash == current_map_hash)
{ {
pc_gain_action(p); pc_gain_action(p);
p->actions=pc_get_actions(p); p->actions=MAX(1, postavy[i].vlastnosti[VLS_POHYB]/15);
// if (p->actions) autostart_round=0; // if (p->actions) autostart_round=0;
} }
else postavy[i].actions=0; else postavy[i].actions=0;
@ -1181,14 +1206,22 @@ void pouzij_zbran(THUMAN *p,int ruka)
mm=vyber_potvoru(p->sektor,p->direction,&chaos); mm=vyber_potvoru(p->sektor,p->direction,&chaos);
if (mm>=0) if (mm>=0)
{ {
TITEM *it=glob_items+itm-1; TITEM *it=itm?glob_items+itm-1:NULL;
m=mobs+mm; m=mobs+mm;
bott_draw(1); bott_draw(1);
anim_mirror=ruka==0; anim_mirror=ruka==0;
prejdi_na_pohled(p); prejdi_na_pohled(p);
if (itm) play_weapon_anim(it->weapon_attack,it->hitpos); if (itm) play_weapon_anim(it->weapon_attack,it->hitpos);
if (utok_na_sektor(p,m,chaos,bonus)>0 && itm && (int)rnd(100)+1<it->magie) if (utok_na_sektor(p,m,chaos,bonus,it==NULL || it->umisteni == PL_OBOUR?0:where)>0 && itm ) {
thing_cast(it->spell,p-postavy,p->sektor,m,1); int roll = (int)rnd(100)+1;
char cast = roll <it->magie;
if (cast) {
if (log_combat) wzprintf(" Weapon cast: %s - %d (roll) > %d (probability)\n",it->jmeno, roll, it->magie);
thing_cast(it->spell,p-postavy,p->sektor,m,1);
}
}
} }
} }
else else
@ -1904,6 +1937,27 @@ char mask_click_help_clear(int id,int xa,int ya,int xr,int yr)
return 1; return 1;
} }
static char clk_fly_cursor(int id,int xa,int ya,int xr,int yr)
{
id;
if (spell_cast)
{
spell_cast=0;
pick_set_cursor();
return 1;
}
if (xr<160) {
souboje_turn(-1);
} else if (xr > 480) {
souboje_turn(1);
} else {
return 0;
}
return 1;
}
static void zahajit_kolo(char prekvapeni) static void zahajit_kolo(char prekvapeni)
{ {
int i,j; int i,j;
@ -2027,7 +2081,7 @@ void fix_group_direction()
if (postavy[i].used && postavy[i].groupnum==g && !postavy[i].programovano) postavy[i].direction=viewdir; if (postavy[i].used && postavy[i].groupnum==g && !postavy[i].programovano) postavy[i].direction=viewdir;
} }
void souboje_turn(int smer) static void souboje_turn(int smer)
{ {
if (pass_zavora) return; if (pass_zavora) return;
norefresh=1; norefresh=1;
@ -2257,15 +2311,15 @@ char zasah_veci(int sector,TFLY *fl)
if (m2 == NULL) { if (m2 == NULL) {
mob_hit(m1, mob_hit(m1,
vypocet_zasahu(it->zmeny, m1->vlastnosti, 1, fl->damage, vypocet_zasahu(it->zmeny, m1->vlastnosti, 1, fl->damage,
fl->hit_bonus)); fl->hit_bonus,0));
m1->dir = (fl->smer + 2) & 3; m1->dir = (fl->smer + 2) & 3;
} else { } else {
mob_hit(m1, mob_hit(m1,
vypocet_zasahu(it->zmeny, m1->vlastnosti, 2, fl->damage, vypocet_zasahu(it->zmeny, m1->vlastnosti, 2, fl->damage,
fl->hit_bonus)); fl->hit_bonus,0));
mob_hit(m2, mob_hit(m2,
vypocet_zasahu(it->zmeny, m1->vlastnosti, 2, fl->damage, vypocet_zasahu(it->zmeny, m1->vlastnosti, 2, fl->damage,
fl->hit_bonus)); fl->hit_bonus,0));
m1->dir = (fl->smer + 2) & 3; m1->dir = (fl->smer + 2) & 3;
m2->dir = (fl->smer + 2) & 3; m2->dir = (fl->smer + 2) & 3;
} }
@ -2288,7 +2342,7 @@ char zasah_veci(int sector,TFLY *fl)
short vlastnosti[VLS_MAX]; short vlastnosti[VLS_MAX];
memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti)); memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti));
if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti); if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti);
death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus),1); death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus,0),1);
if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva
c=1; c=1;
} }
@ -2318,7 +2372,7 @@ char zasah_veci(int sector,TFLY *fl)
if (abs(x1-m1->locx+128)+abs(y1-m1->locy+128)>abs(x1-m2->locx+128)+abs(y1-m2->locy+128)) m1=m2; if (abs(x1-m1->locx+128)+abs(y1-m1->locy+128)>abs(x1-m2->locx+128)+abs(y1-m2->locy+128)) m1=m2;
} }
if (m1->vlajky & MOB_PASSABLE) return 0; if (m1->vlajky & MOB_PASSABLE) return 0;
mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,(m2!=NULL)+1,fl->damage,fl->hit_bonus)); mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,(m2!=NULL)+1,fl->damage,fl->hit_bonus,0));
if (it->druh==TYP_VRHACI) fl->flags|=FLY_DESTROY; if (it->druh==TYP_VRHACI) fl->flags|=FLY_DESTROY;
if (it->umisteni!=PL_SIP && !(it->flags & ITF_DESTROY)) if (it->umisteni!=PL_SIP && !(it->flags & ITF_DESTROY))
{ {
@ -2347,7 +2401,7 @@ char zasah_veci(int sector,TFLY *fl)
short vlastnosti[VLS_MAX]; short vlastnosti[VLS_MAX];
memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti)); memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti));
if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti);else uprav_podle_kondice(p,&kolik); if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti);else uprav_podle_kondice(p,&kolik);
death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus),1); death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus,0),1);
if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva
c=1; c=1;
} }
@ -2463,7 +2517,7 @@ void send_experience(TMOB *p,int dostal)
if (dostal>0) { if (dostal>0) {
int exp = ((float)p->experience*(float)dostal/p->vlastnosti[VLS_MAXHIT]); int exp = ((float)p->experience*(float)dostal/p->vlastnosti[VLS_MAXHIT]);
if (log_combat && p->bonus) { if (log_combat && p->bonus) {
wzprintf("%s experience: %d\n", postavy[select_player].jmeno, p->bonus); wzprintf("%s experience: %d\n", postavy[select_player].jmeno, exp);
} }
postavy[select_player].exp+=(int32_t)exp; postavy[select_player].exp+=(int32_t)exp;
@ -2552,6 +2606,7 @@ char player_hit(THUMAN *p,int zraneni,char manashield)
{ {
THE_TIMER *tt;int h; THE_TIMER *tt;int h;
if (log_combat) wzprintf("%s was hit: %d, lives: %d\n", p->jmeno, zraneni, p->lives-zraneni);
if (zraneni>p->lives) zraneni=p->lives; if (zraneni>p->lives) zraneni=p->lives;
p->dostal=zraneni; p->dostal=zraneni;
if (manashield) manashield_check(p->vlastnosti,&p->lives,&p->mana,p->dostal); //manashield pro hrace if (manashield) manashield_check(p->vlastnosti,&p->lives,&p->mana,p->dostal); //manashield pro hrace

View file

@ -69,6 +69,18 @@ int str_add(TSTR_LIST *list,const char *text)
return i; return i;
} }
int str_move_list(TSTR_LIST to, TSTR_LIST from) {
int cnt1 = str_count(from);
int cnt2 = str_count(to);
int cnt = MIN(cnt1,cnt2);
for (int i = 0; i < cnt; ++i) {
if (to[i]) free(to[i]);
to[i] = from[i];
from[i] = NULL;
}
return cnt;
}
const char *str_insline(TSTR_LIST *list,int before,const char *text) const char *str_insline(TSTR_LIST *list,int before,const char *text)
{ {
int i,count,punkt; int i,count,punkt;

View file

@ -19,6 +19,7 @@ void str_remove(TSTR_LIST *list,int line);
void str_delfreelines(TSTR_LIST *list); void str_delfreelines(TSTR_LIST *list);
int str_count(TSTR_LIST p); int str_count(TSTR_LIST p);
void release_list(TSTR_LIST list); void release_list(TSTR_LIST list);
int str_move_list(TSTR_LIST to, TSTR_LIST from);
TSTR_LIST sort_list(TSTR_LIST list,int direction); TSTR_LIST sort_list(TSTR_LIST list,int direction);
TSTR_LIST read_directory(const char *mask,int view_type,int attrs); TSTR_LIST read_directory(const char *mask,int view_type,int attrs);
//void name_conv(const char *c); //void name_conv(const char *c);

View file

@ -121,21 +121,28 @@ int list_files(const char *directory, int type, LIST_FILES_CALLBACK cb, void *ct
int r = 0; int r = 0;
const auto &entry = *iter; const auto &entry = *iter;
const char *name; const char *name;
size_t szortm = 0;
std::string tmp; std::string tmp;
if (type & file_type_just_name) { if (type & file_type_just_name) {
tmp = entry.path().filename().string(); tmp = entry.path().filename().string();
} else { } else {
tmp = entry.path().string(); tmp = entry.path().string();
}
if (type & file_type_need_timestamp) {
auto tm = std::chrono::clock_cast<std::chrono::system_clock>(entry.last_write_time(ec));
szortm = std::chrono::system_clock::to_time_t(tm);
} else {
szortm = entry.file_size(ec);
} }
name = tmp.c_str(); name = tmp.c_str();
if (entry.is_regular_file(ec) && (type & file_type_normal)) { if (entry.is_regular_file(ec) && (type & file_type_normal)) {
r = cb(name, file_type_normal, entry.file_size(ec), ctx); r = cb(name, file_type_normal, szortm, ctx);
} else if (entry.is_directory(ec)) { } else if (entry.is_directory(ec)) {
int dot = entry.path().filename() == "." || entry.path().filename() == ".."; int dot = entry.path().filename() == "." || entry.path().filename() == "..";
if (!dot && (type & file_type_directory)) { if (!dot && (type & file_type_directory)) {
r = cb(name, file_type_directory, 0, ctx); r = cb(name, file_type_directory, szortm, ctx);
} else if (dot & (type & file_type_dot)) { } else if (dot & (type & file_type_dot)) {
r = cb(name, file_type_dot, 0, ctx); r = cb(name, file_type_dot, szortm, ctx);
} }
} }
if (r) return r; if (r) return r;

View file

@ -17,9 +17,19 @@
#pragma warning(disable: 4457) #pragma warning(disable: 4457)
#pragma warning(disable: 4702) #pragma warning(disable: 4702)
#pragma warning(disable: 4100) #pragma warning(disable: 4100)
//microsoft doesn't support FALLTHROUGH
#define CASE_FALLTHROUGH #define CASE_FALLTHROUGH
//microsoft doesn't support VLA
#define DECL_VLA(type, variable, count) type *variable = (type *)alloca((count)*sizeof(type));
#define GET_VLA_SIZE(variable, count) ((count)*sizeof(*variable))
#else #else
//support FALLTHROUGH
#define CASE_FALLTHROUGH [[fallthrough]] #define CASE_FALLTHROUGH [[fallthrough]]
//support VLA
#define DECL_VLA(type, variable, count) type variable[count];
#define GET_VLA_SIZE(variable, count) sizeof(variable)
#endif #endif
@ -90,6 +100,7 @@ const char *file_icase_find(const char *pathname);
int istrcmp(const char *a, const char *b); int istrcmp(const char *a, const char *b);
int istrncmp(const char *a, const char *b, size_t sz); int istrncmp(const char *a, const char *b, size_t sz);
int imatch(const char *haystack, const char *needle); int imatch(const char *haystack, const char *needle);
#define SAFESTRCOPY(target, source) strcopy_n(target, source, sizeof(target) )
const char *strcopy_n(char *target, const char *source, int target_size); const char *strcopy_n(char *target, const char *source, int target_size);
#define MIN(a, b) ((a)<(b)?(a):(b)) #define MIN(a, b) ((a)<(b)?(a):(b))
#define MAX(a, b) ((a)>(b)?(a):(b)) #define MAX(a, b) ((a)>(b)?(a):(b))
@ -104,7 +115,8 @@ typedef enum {
file_type_normal = 1, file_type_normal = 1,
file_type_directory = 2, file_type_directory = 2,
file_type_dot = 4, file_type_dot = 4,
file_type_just_name = 8 file_type_just_name = 8,
file_type_need_timestamp = 16
} LIST_FILE_TYPE; } LIST_FILE_TYPE;
typedef int (*LIST_FILES_CALLBACK)(const char *, LIST_FILE_TYPE , size_t, void *); typedef int (*LIST_FILES_CALLBACK)(const char *, LIST_FILE_TYPE , size_t, void *);