diff --git a/game/builder.c b/game/builder.c index e100514..e9ad729 100644 --- a/game/builder.c +++ b/game/builder.c @@ -327,14 +327,14 @@ static const void *bott_draw_normal(const void *pp, int32_t *s) { char c[]=" ";int z,lv,llv; put_picture(x,0,ablock(H_OKNO));lv=p->lives;llv=p->vlastnosti[VLS_MAXHIT]; - if (lv || p->used & 0x80 || p->kondice > 0) + if (lv || p->used & 0x80) { z=3-((lv-1)*4/llv);if (lv==llv) z=0; z*=75; if (p->xicht>=0)put_8bit_clipped(ablock(H_XICHTY+i),bott_scr+PIC_X+x+PIC_Y*scr_linelen2,z,54,75); - if (!lv && !(p->used & 0x80) && p->kondice>0) { + /* if (!lv && !(p->used & 0x80) && p->kondice>0) { greyscale_rectangle(PIC_X+x,PIC_Y, 54, 75); - } + }*/ if (p->bonus) draw_small_icone(0,PIC_X+x+1,PIC_Y+1); if (p->spell) draw_small_icone(1,PIC_X+x+1,PIC_Y+1); if (!p->voda) draw_small_icone(2,PIC_X+x+1,PIC_Y+1); diff --git a/game/enemy.c b/game/enemy.c index 7a5811c..d2a2a1f 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -1317,18 +1317,24 @@ void vymaz_zasahy(THE_TIMER *q) bott_draw(0); } +static int select_drop_inventory_place(TMOB *p) { + int x,y,pl; + if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1; + if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1; + pl=0;if (x>0) pl++; + if (y>0) pl=3-pl; + return pl; +} + static int drop_inventory(TMOB *p) { - int i,x,y,pl; + int i,pl; short c[]={0,0}; - for(i=-1;iinv[i] || (i<0 && p->money)) { - if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1; - if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1; - pl=0;if (x>0) pl++; - if (y>0) pl=3-pl; + pl = select_drop_inventory_place(p); if (i<0) { int z=(int)p->money+(int)(rnd(40)-20)*(int)p->money/(int)100; @@ -1341,6 +1347,16 @@ static int drop_inventory(TMOB *p) } push_item(p->sector,pl,c); } + } + if (destroyed_items) { + int cnt = count_items_total(destroyed_items); + if (cnt) { + int idx = cnt -1; + pl = select_drop_inventory_place(p); + push_item(p->sector,pl, destroyed_items+idx); + destroyed_items[idx] = 0; + } + } return 0; } diff --git a/game/gamesave.c b/game/gamesave.c index 6b00782..f87b217 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -30,6 +30,9 @@ #define SLOTS_MAX 10 #define GM_MAPENABLE 0x1 +#define GM_FASTBATTLES 0x2 +#define GM_GAMESPEED_SHIFT 2 +#define GM_GAMESPEED_MASK 0x1F #define SAVE_SLOT_S 34 #define LOAD_SLOT_S (372+34) @@ -583,6 +586,14 @@ int unpack_all_status(FILE *f) return -1; } +static void save_destroyed_items(TMPFILE_WR *f) { + short c = (short)count_items_total(destroyed_items); + temp_storage_write(&c,sizeof(c), f); + if (c) { + temp_storage_write(destroyed_items,sizeof(short)*c, f); + } +} + int save_basic_info() { TMPFILE_WR *f; @@ -618,7 +629,14 @@ int save_basic_info() s.swapchans=MIN(get_snd_effect(SND_SWAP),255); s.out_filter=MIN(get_snd_effect(SND_OUTFILTER),255); s.autosave=autosave_enabled; - s.game_flags=(enable_glmap!=0); + s.game_flags=0; + + if (enable_glmap!=0) s.game_flags |= GM_MAPENABLE; + if (gamespeedbattledemon_save!=NULL) temp_storage_write(h->demon_save,sizeof(THUMAN)*1,f); //ulozeni polozek s demony res|=save_dialog_info(f); + save_destroyed_items(f); temp_storage_close_wr(f); SEND_LOG("(SAVELOAD) Done... Result: %d",res); return res; } +static int load_destroyed_items(TMPFILE_RD *f) { + int res = 0; + short destroyed_items_count = 0; + temp_storage_read(&destroyed_items_count,sizeof(destroyed_items_count), f); + free(destroyed_items); + destroyed_items = NULL; + if (destroyed_items_count) { + destroyed_items = NewArr(short, destroyed_items_count+1); + res|=temp_storage_read(destroyed_items,destroyed_items_count*sizeof(short), f) != destroyed_items_count*sizeof(short); + destroyed_items[destroyed_items_count] = 0; + } + return res; +} + int load_basic_info() { TMPFILE_RD *f; @@ -654,6 +687,9 @@ int load_basic_info() if (f==NULL) return 1; res|=(temp_storage_read(&s,1*sizeof(s),f)!=sizeof(s)); if (s.game_flags & GM_MAPENABLE) enable_glmap=1;else enable_glmap=0; + gamespeedbattle =s.game_flags & GM_FASTBATTLES? GAMESPEED_FASTBATTLE:gamespeed; + int tmsp = (s.game_flags >> GM_GAMESPEED_SHIFT) & GM_GAMESPEED_MASK; + if (tmsp) timerspeed_val = tmsp; i=s.picks; if (picked_item!=NULL) free(picked_item); if (i) @@ -685,6 +721,7 @@ int load_basic_info() } } res|=load_dialog_info(f); + res|=load_destroyed_items(f); temp_storage_close_rd(f); viewsector=s.viewsector; viewdir=s.viewdir; diff --git a/game/globals.h b/game/globals.h index bc5d4e3..b5381bd 100644 --- a/game/globals.h +++ b/game/globals.h @@ -12,6 +12,10 @@ #define POCET_POSTAV 6 #define HODINA 360 +#define GAMESPEED 5 +#define GAMESPEED_FASTBATTLE 2 + + #define MAX_FILESYSTEM_PATH 256 #define A_SIDEMAP 0x8001 @@ -573,6 +577,7 @@ extern int mapsize; //pocet sektoru v mape extern int hl_ptr; //ukazatel na konec staticke tabulky registraci extern int end_ptr; //ukazatel na uplny konec tabulky registraci extern short **map_items; //ukazatel na mapu predmetu +extern short *destroyed_items; //list of destroyed items to be returned to the game extern int default_ms_cursor; //cislo zakladniho mysiho kurzoru extern void (*unwire_proc)(void); //procedura zajistujici odpojeni prave ukoncovane interakce extern void (*wire_proc)(void); //procedura zajistujici pripojeni drive ukoncene interakce @@ -581,8 +586,8 @@ extern word minimap[VIEW3D_Z+1][VIEW3D_X*2+1]; //minimalizovana mapa s informace extern char norefresh; //vypina refresh obrazovky extern char cancel_pass; //okamzite zrusi plynuly prechod extern char reverse_draw ; //kresba odpredu dozadu -extern char gamespeed; //rychlost hry -extern char gamespeedbattle; //akcelerace rychlosti pro bitvy +extern uint8_t gamespeed; //rychlost hry +extern uint8_t gamespeedbattle; //akcelerace rychlosti pro bitvy extern int num_ofsets[]; //tabulka offsetu pro steny extern int back_color; //cislo barvy pozadi extern uint8_t cur_group; //cislo aktualni skupiny @@ -986,10 +991,10 @@ char pick_item_(int id,int xa,int ya,int xr,int yr); void wire_inv_mode(THUMAN *select); void init_inventory(void); void init_items(void); -void push_item(int sect,int pos,short *picked_item); +void push_item(int sect,int pos,const short *picked_item); void pop_item(int sect,int pos,int mask,short **picked_item); -int count_items_inside(short *place); -int count_items_total(short *place); +int count_items_inside(const short *place); +int count_items_total(const short *place); char put_item_to_inv(THUMAN *p,short *picked_items); //funkce vklada predmet(y) do batohu postavy void pick_set_cursor(void); //nastavuje kurzor podle vlozeneho predmetu; void calc_fly(THE_TIMER *t); diff --git a/game/interfac.c b/game/interfac.c index c241815..188df8c 100644 --- a/game/interfac.c +++ b/game/interfac.c @@ -1486,8 +1486,9 @@ int smlouvat_prodej(int cena,int ponuka,int posledni,int puvod,int pocet) if (ponuka==0) return 0; if (ponuka<=cena) return 0; - if (posledni!=0) if (ponuka>=posledni || ponuka>min) return 1; - if (p_ok>r_ok) return 0; + if (ponuka <= min && (posledni==0 || ponukar_ok) return 0; + } if (p_ok>75) return 2; if (p_ok>50) return 3; if (p_ok>25) return 4; @@ -1544,7 +1545,7 @@ THAGGLERESULT smlouvat_dlg(int cena,int puvod,int pocet,int posledni, int money, define(-1,150,15,100,13,0,label,int2ascii(cena,buffer,10)); set_font(H_FBOLD,MSG_COLOR1); define(-1,10,30,1,1,0,label,texty[238]); - define(10,150,30,100,13,0,input_line,8,0,0,"");property(def_border(5,BAR_COLOR),NULL,NULL,0);set_default(""); + define(10,150,30,100,13,0,input_line,7,0,0,"");property(def_border(5,BAR_COLOR),NULL,NULL,0);set_default(""); on_control_event(smlouvat_enter); define(20,20,20,80,20,2,button,texty[239]);property(def_border(5,BAR_COLOR),NULL,NULL,BAR_COLOR);on_control_change(terminate_gui); define(30,110,20,80,20,2,button,texty[230]);property(def_border(5,BAR_COLOR),NULL,NULL,BAR_COLOR);on_control_change(terminate_gui); diff --git a/game/inv.c b/game/inv.c index 43b497d..27d16b6 100644 --- a/game/inv.c +++ b/game/inv.c @@ -432,7 +432,7 @@ void draw_placed_items_normal(int celx,int cely,int sect,int side) } } -int count_items_total(short *place) +int count_items_total(const short *place) { int c=0; @@ -441,7 +441,7 @@ int count_items_total(short *place) return c; } -int count_items_visible(short *place) +int count_items_visible(const short *place) { int c=0; @@ -455,7 +455,7 @@ int count_items_visible(short *place) } -int count_items_inside(short *place) +int count_items_inside(const short *place) { int c=1; @@ -479,43 +479,37 @@ int find_item(short *place,int mask) return lastitem; } -static int lastsector; - -static char ValidateSector(word sector, void *_) - { - int pp=map_sectors[sector].sector_type; - if (pp==S_NORMAL || pp==S_SMER || pp==S_LEAVE || pp==S_FLT_SMER) - { - lastsector=sector; - return 1; - } - return 0; +void push_to_destroyed_items(const short *picked_items) { + int new_count = count_items_total(picked_items); + if (new_count == 0) return; + int cur_destroyed = count_items_total(destroyed_items); + short *nw = NewArr(short, new_count+cur_destroyed+1); + for (int i = 0; i < new_count; ++i) { + nw[i] = abs(picked_items[i]); } + for (int i = 0; i < cur_destroyed; ++i) { + nw[new_count+i] = destroyed_items[i]; + } + nw[new_count+cur_destroyed] = 0; + free(destroyed_items); + destroyed_items = nw; +} -void push_item(int sect,int pos,short *picked_item) +void push_item(int sect,int pos,const short *picked_item) { int bc; int pc; int tc; short *p; + char s = map_sectors[sect].sector_type; - if (map_sectors[sect].sector_type==S_DIRA || ISTELEPORTSECT(sect)) + + if (s==S_DIRA || ISTELEPORTSECT(sect) || s == S_SCHODY) sect=map_sectors[sect].sector_tag; - if (sect==0 || map_sectors[sect].sector_type==S_VODA) - { - if (game_extras & EX_RECOVER_DESTROYED_ITEMS) - { - labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,ValidateSector,NULL, NULL); - push_item(lastsector,viewdir,picked_item); - return; - } - else - { - free(picked_item); - picked_item=NULL; - return; - } - } + if (sect==0 || s==S_VODA || s == S_LAVA || s == S_SSMRT || s == S_LODKA) { + push_to_destroyed_items(picked_item); + return; + } sect=(sect<<2)+pos; bc=count_items_total(map_items[sect]); pc=count_items_total(picked_item); @@ -682,7 +676,7 @@ char pick_item_(int id,int xa,int ya,int xr,int yr) idd=(id+viewdir)&0x3; if (picked_item!=NULL) { - if (map_sectors[sect].sector_type==S_DIRA) + if (map_sectors[sect].sector_type==S_DIRA) { throw_fly(xa,ya,0); letici_veci->speed=0; @@ -2494,7 +2488,6 @@ static int shop_sector; T_CLK_MAP clk_shop[]= { {-1,54,378,497,479,shop_change_player,2+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,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}, {2,246+BUYBOX_X,39+BUYBOX_Y,266+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT}, @@ -2503,6 +2496,7 @@ T_CLK_MAP clk_shop[]= {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {-1,0,0,639,479,_exit_shop,8,-1}, }; static void shop_mouse_event(EVENT_MSG *msg,void **unused) @@ -3207,7 +3201,6 @@ char _exit_shop(int id, int xa, int ya,int xr,int yr) { xr,yr,xa,ya,id; SEND_LOG("(SHOP) Exiting shop..."); - memset(shp_item_map, 0, sizeof(shp_item_map)); if (cur_owner==-1) { free(picked_item); diff --git a/game/realgame.c b/game/realgame.c index 80fd10c..e946bd5 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -62,7 +62,8 @@ TSTENA *map_sides; TSECTOR *map_sectors; TVYKLENEK *map_vyk; //mapa vyklenku word vyk_max; //pocet vyklenku v mape -short **map_items; +short **map_items = 0; +short *destroyed_items = 0;; char *flag_map; TMAP_EDIT_INFO *map_coord; TSTR_LIST level_texts; diff --git a/game/setup.c b/game/setup.c index 28118e3..bff5d7b 100644 --- a/game/setup.c +++ b/game/setup.c @@ -44,7 +44,7 @@ static void checkbox_animator(THE_TIMER *t) animate_checkbox(10,130,10); } -static int effects[]={SND_GVOLUME,SND_MUSIC,SND_GFX,SND_TREBL,SND_BASS,SND_XBASS}; +static int effects[]={SND_GVOLUME,SND_MUSIC,SND_GFX,SND_TREBL,SND_BASS}; static void do_setup_change(void) { @@ -55,6 +55,7 @@ static void do_setup_change(void) { case 10:set_snd_effect(SND_SWAP,c & 1);break; case 20:set_snd_effect(SND_OUTFILTER,c & 1);break; + case 250:timerspeed_val = TIMERSPEED- c;break; default:set_snd_effect(effects[o_aktual->id/10-20],c);break; } } @@ -111,7 +112,7 @@ static void unwire_setup(void) enable_sort=f_get_value(0,100) & 1; autoattack=f_get_value(0,110) & 1; autosave_enabled=f_get_value(0,120) & 1; - level_preload=f_get_value(0,130) & 1; + gamespeedbattle=(f_get_value(0,130) & 1)?GAMESPEED_FASTBATTLE:gamespeed; delete_from_timer(TM_CHECKBOX); mix_back_sound(32768); close_current(); @@ -188,7 +189,7 @@ void new_setup() case 1:c_default(enable_sort);break; case 2:c_default(autoattack);break; case 3:c_default(autosave_enabled);break; - case 4:c_default(level_preload);break; + case 4:c_default(gamespeedbattle < gamespeed);break; } } @@ -201,6 +202,9 @@ void new_setup() define(200+i*10,50+i*60,30,30,200,0,skeldal_soupak,effects[i]==SND_MUSIC?127:255);c_default(get_snd_effect(effects[i])); on_control_change(do_setup_change); } + define(200+5*10,50+5*60,30,30,200,0,skeldal_soupak,TIMERSPEED-1);c_default(timerspeed_val >TIMERSPEED?0:TIMERSPEED - timerspeed_val); + on_control_change(do_setup_change); + define(300,559,336,81,21,0,setup_ok_button,texty[174]);on_control_change(exit_setup_action); property(NULL,ablock(H_FTINY),&color_topbar,0); redraw_window(); diff --git a/game/skeldal.c b/game/skeldal.c index 28d488e..e126c04 100644 --- a/game/skeldal.c +++ b/game/skeldal.c @@ -75,12 +75,13 @@ typedef struct inis THE_TIMER timer_tree; + int hl_ptr=H_FIRST_FREE; int debug_enabled=0; char sound_detection=1; int snd_devnum,snd_parm1,snd_parm2,snd_parm3,snd_mixing=22000; -char gamespeed=5; -char gamespeedbattle=0; +uint8_t gamespeed=GAMESPEED; +uint8_t gamespeedbattle=GAMESPEED; char level_preload=1; char *level_fname=NULL; int game_extras=0; @@ -823,6 +824,8 @@ void cti_texty(void) //patch stringtable if (!texty[98]) str_replace(&texty,98,"Ulo\x91it hru jako"); if (!texty[99]) str_replace(&texty,99,"CRT Filter (>720p)"); + str_replace(&texty, 144, "Zrychlit souboje"); + str_replace(&texty, 51, "Celkov\x88 Hudba Efekty V\x98\xA8ky Basy Rychlost"); str_replace(&texty,0,"Byl nalezen p\xA9ipojen\x98 ovlada\x87\nPro aktivaci ovlada\x87""e stiskn\x88te kter\x82koliv tla\x87\xA1tko na ovlada\x87i"); lang_patch_stringtable(&texty, "ui.csv", ""); } diff --git a/game/souboje.c b/game/souboje.c index fdf925a..6cd3890 100644 --- a/game/souboje.c +++ b/game/souboje.c @@ -879,7 +879,7 @@ char JePozdrzeno() void pozdrz_akci() { - int battlespeed=gamespeed-gamespeed*gamespeedbattle/5; + int battlespeed=gamespeedbattle; SPozdrzeno=get_game_tick_count()+battlespeed*2000/6; } @@ -1146,7 +1146,7 @@ static void pouzij_svitek(THUMAN *p,int ruka) static void play_weapon_anim(int anim_num,int hitpos) { char count_save=global_anim_counter; - int battlespeed=gamespeed-gamespeed*gamespeedbattle/5; + int battlespeed=gamespeedbattle; if (anim_num==0) return; hold_timer(TM_SCENE,1); @@ -1453,7 +1453,7 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje void wire_jadro_souboje(void) { - int battlespeed=gamespeed-gamespeed*gamespeedbattle/5; + int battlespeed=gamespeedbattle; recalc_volumes(viewsector,viewdir); if (battlespeed<1) battlespeed=1; add_to_timer(TM_SCENE,battlespeed,-1,hrat_souboj); diff --git a/lang/en/ui.csv b/lang/en/ui.csv index 7703124..98046c6 100644 --- a/lang/en/ui.csv +++ b/lang/en/ui.csv @@ -45,7 +45,7 @@ To activate the controller, press any button on the controller" 48,Start 49,Throw 50,Combat in Progress -51,Overall Music Sounds Treble Bass +51,Overall Music Sounds Treble Bass Speed 52,Stereo Settings (Ultrasound) 53,Swap Sides 54,Output Filter (SBPro) @@ -117,7 +117,7 @@ To activate the controller, press any button on the controller" 141,Rearrange Portraits 142,Auto Attack 143,Auto Save -144,Load All Into Memory +144,Speed up battles 145,Adventure Length: 146,%d day and 147,%d days and diff --git a/platform/sdl/sound.cpp b/platform/sdl/sound.cpp index 6c2c562..2885308 100644 --- a/platform/sdl/sound.cpp +++ b/platform/sdl/sound.cpp @@ -299,7 +299,8 @@ static void update_music_volume(){ float v = music_volume * master_volume; for (int i = 0; i <2; i++) sound_mixer.visit_track(music_track_id_base+i,[&](WaveMixer<2> &m){ - m.set_channel_volume(v, v); + m.set_channel_volume(0, v); + m.set_channel_volume(1, v); }); } diff --git a/tools/ddl_ar_class.cpp b/tools/ddl_ar_class.cpp index 0142254..e59a8bb 100644 --- a/tools/ddl_ar_class.cpp +++ b/tools/ddl_ar_class.cpp @@ -45,7 +45,7 @@ DDLArchive::Extracted DDLArchive::extract_file(std::ifstream &s, std::vector data; data.resize(sz); s.read(data.data(), sz); - if (s.gcount() != sz) return {fname, false, {}}; + if (static_cast(s.gcount()) != sz) return {fname, false, {}}; return {fname, true, std::move(data)}; }