diff --git a/game/automap.c b/game/automap.c index c59b8b5..90f8cce 100644 --- a/game/automap.c +++ b/game/automap.c @@ -22,6 +22,7 @@ #define AUTOMAP_VODA RGB555(0,15,31) #define AUTOMAP_LAVA RGB555(31,16,0) #define AUTOMAP_FORE RGB555(18,17,14) +#define AUTOMAP_FORE_LVP RGB555(14,13,11) #define AUTOMAP_LINE1 RGB555(13,11,10) #define AUTOMAP_LINE2 RGB555(31,22,6) #define AUTOMAP_MOB RGB555(31,8,8) @@ -382,6 +383,7 @@ static void draw_amap_sector(int x,int y,int sector,int mode,int turn,int line1, ss=&map_sectors[sector]; if (ss->sector_type==S_VODA || ss->sector_type==S_LODKA) curcolor=AUTOMAP_VODA; else if (ss->sector_type==S_LAVA) curcolor=AUTOMAP_LAVA; + else if (ss->sector_type==S_LEAVE) curcolor=AUTOMAP_FORE_LVP; else curcolor=AUTOMAP_FORE; if (!mode) { @@ -594,7 +596,7 @@ void draw_automap(int xr,int yr) ukaz_mysku(); showview(0,16,640,360); } -void *map_keyboard(EVENT_MSG *msg,void **usr); +void map_keyboard(EVENT_MSG *msg,void **usr); void enable_all_map(void) { @@ -613,7 +615,6 @@ void unwire_automap(void) { send_message(E_DONE,E_KEYBOARD,map_keyboard); send_message(E_DONE,E_AUTOMAP_REDRAW,map_keyboard); - send_message(E_DONE,E_IDLE,map_keyboard); hold_timer(TM_FAST_TIMER,0); disable_all_map(); noarrows=0; @@ -622,43 +623,92 @@ void unwire_automap(void) GlobEvent(MAGLOB_AFTERMAPOPEN,viewsector,viewdir); } -void *map_keyboard(EVENT_MSG *msg,void **usr) + + +void map_keyboard(EVENT_MSG *msg,void **usr) { char c; - int draw=0; static int xr,yr; usr; - if (msg->msg==E_INIT) xr=yr=0; - if (msg->msg==E_AUTOMAP_REDRAW) draw=4; + if (msg->msg==E_INIT) { + xr=va_arg(msg->data,int); + yr=va_arg(msg->data,int); + } if (msg->msg==E_KEYBOARD) { int d = quit_request_as_escape(va_arg(msg->data, int)); c=d>>8; switch (c) { - case 'H':yr++;draw=4;break; - case 'P':yr--;draw=4;break; - case 'M':xr--;draw=4;break; - case 'K':xr++;draw=4;break; + case 'H':yr++;break; + case 'P':yr--;break; + case 'M':xr--;break; + case 'K':xr++;break; case 'Q': - case 's':if (check_for_layer(cur_depth-1)) cur_depth--;draw=4;break; + case 's':if (check_for_layer(cur_depth-1)) cur_depth--;break; case 'I': - case 't':if (check_for_layer(cur_depth+1)) cur_depth++;draw=4;break; + case 't':if (check_for_layer(cur_depth+1)) cur_depth++;break; case 15: case 50: case 1: unwire_proc(); wire_proc(); - break; + return; } - if (draw) { - draw_automap(xr,yr); } - } - return &map_keyboard; + draw_automap(xr,yr); + + return; } +typedef struct { + int left, top, right, bottom; +} TMAP_RECT; + +static TMAP_RECT get_map_rect() { + TMAP_RECT rc = {}; + char first = 1; + for(int i=1;i rc.right) rc.right = xp; + if (yp > rc.bottom) rc.bottom = yp; + } + } + } + return rc; +} + +static TMAP_RECT get_screen_rect() { + TMAP_RECT rc; + rc.left = -35; + rc.right = 35; + rc.top = -18; + rc.bottom = 18; + return rc; +} + +static void shift_map_to_center(TMAP_RECT map_rect, int mx, int my, int *xr, int *yr) { + TMAP_RECT screen_rect = get_screen_rect(); + int dx = (map_rect.left+map_rect.right)/2-mx; // + int dy = (map_rect.top+map_rect.bottom)/2-my; + if (dx < screen_rect.left) dx = screen_rect.left; + if (dx > screen_rect.right) dx = screen_rect.right; + if (dy < screen_rect.top) dy = screen_rect.top; + if (dy > screen_rect.bottom) dy = screen_rect.bottom;; + *xr = -dx; + *yr = -dy; +} + void show_automap(char full) { mute_all_tracks(0); @@ -674,10 +724,15 @@ void show_automap(char full) ukaz_mysku(); showview(0,376,640,480); cur_depth=map_coord[viewsector].layer; - draw_automap(0,0); - send_message(E_ADD,E_KEYBOARD,map_keyboard); - send_message(E_ADD,E_AUTOMAP_REDRAW,map_keyboard); - send_message(E_ADD,E_IDLE,map_keyboard); + int xm = map_coord[viewsector].x; + int ym = map_coord[viewsector].y; + int xr; + int yr; + shift_map_to_center(get_map_rect(), xm, ym, &xr, &yr); + draw_automap(xr,yr); + + send_message(E_ADD,E_KEYBOARD,map_keyboard,xr,yr); + send_message(E_ADD,E_AUTOMAP_REDRAW,map_keyboard,xr,yr); change_click_map(clk_map_view,CLK_MAP_VIEW); } @@ -928,7 +983,7 @@ void map_teleport_keyboard(EVENT_MSG *msg,void **usr) } -static char path_ok(word sector) +static char path_ok(word sector, void *ctx) { map_coord[sector].flags|=MC_MARKED; return 1; @@ -950,7 +1005,7 @@ char map_target_select(int id,int xa,int ya,int xr,int yr) y2=y1+8; if (xr>=x1 && xr<=x2 && yr>=y1 && yr<=y2) { - if (!labyrinth_find_path(viewsector,id,SD_PLAY_IMPS,path_ok,NULL)) return 0; + if (!labyrinth_find_path(viewsector,id,SD_PLAY_IMPS,path_ok,NULL,NULL)) return 0; last_selected=id; exit_wait=1; return 1; @@ -965,7 +1020,7 @@ int select_teleport_target(void) *otevri_zavoru=1; unwire_proc(); disable_all_map(); - labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,path_ok,NULL); + labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,path_ok,NULL,NULL); map_coord[viewsector].flags|=MC_MARKED; schovej_mysku(); send_message(E_ADD,E_KEYBOARD,map_teleport_keyboard); diff --git a/game/console.c b/game/console.c index 2ca8f2f..d308ff6 100644 --- a/game/console.c +++ b/game/console.c @@ -365,6 +365,7 @@ static char display_game_status(void) void unaffect(); extern char immortality; extern char nohassle; +extern char pass_all_mobs; static char console_input_line[console_max_characters+1] = ""; @@ -494,6 +495,10 @@ static int process_on_off_command(const char *cmd, char on) { game_extras = on?(game_extras | EX_WALKDIAGONAL):(game_extras & ~EX_WALKDIAGONAL); return 1; } + if (stricmp(cmd, "ghost-form") == 0) { + pass_all_mobs = on; + return 1; + } return 0; } diff --git a/game/dialogy.c b/game/dialogy.c index 1a64970..97d34e2 100644 --- a/game/dialogy.c +++ b/game/dialogy.c @@ -563,7 +563,7 @@ static void nahodne(int vls,int omz,char check) memset(chk,0,sizeof(chk)); if (!check) for(i=0;i=omz && chk[i]==0) @@ -963,6 +963,7 @@ char join_character(int i) h->sektor=viewsector; h->direction=viewdir; h->groupnum=cur_group; + h->inmaphash=current_map_hash; reg_grafiku_postav(); bott_draw(1); return 0; @@ -1181,10 +1182,10 @@ static char najist_postavy(int cena) int i,s=0; THUMAN *h=postavy; - for(i=0;iused && h->sektor==viewsector && h->lives && h->inmaphash != current_map_hash) s=s+cena; + for(i=0;iused && h->sektor==viewsector && h->lives) s=s+cena; if (s>money) return 1; money-=s; - for(i=0,h=postavy;iused && h->sektor==viewsector && h->lives && h->inmaphash != current_map_hash) + for(i=0,h=postavy;iused && h->sektor==viewsector && h->lives) { h->jidlo=MAX_HLAD(h); h->voda=MAX_ZIZEN(h); diff --git a/game/enemy.c b/game/enemy.c index 95a5361..54a2de0 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -63,6 +63,7 @@ char battle=0; char neco_v_pohybu=1; char nohassle=0; + typedef struct tmobsavedata { short anim_counter; //citac animaci @@ -1930,18 +1931,23 @@ char track_mob(int sect,int dir) //--------------------------------------------------------------------- /* Nasledujici procedury a funkce se volaji pro chovani potvory v bitve */ -static word last_sector; -static TMOB *fleeing_mob; -static char valid_sectors(word sector) +typedef struct flee_monster_context { + word last_sector; + TMOB *fleeing_mob; + +} TFLEE_MONSTER_CONTEXT; + +static char valid_sectors(word sector, void *ctx) { int pp; + TFLEE_MONSTER_CONTEXT *fmc = (TFLEE_MONSTER_CONTEXT *)ctx; - last_sector=sector; + fmc->last_sector=sector; if (map_coord[sector].flags & MC_MARKED) return 0; //nevyhovujici pp=q_kolik_je_potvor(sector); if (pp==2) return 0; //moc potvor - nevyhovujici - if (fleeing_mob->stay_strategy & MOB_BIG && pp) return 0; + if (fmc->fleeing_mob->stay_strategy & MOB_BIG && pp) return 0; pp=map_sectors[sector].sector_type; if (pp==S_DIRA || ISTELEPORT(pp)) return 0; return 1; @@ -1962,9 +1968,11 @@ char flee_monster_zac(TMOB *m) map_coord[map_sectors[s].step_next[i]].flags |= MC_MARKED; //oznac sektor jako nevyhovujici map_coord[s].flags |= MC_MARKED; } - fleeing_mob=m; - labyrinth_find_path(m->sector,65535,SD_MONST_IMPS,valid_sectors,NULL); - i=labyrinth_find_path(m->sector,last_sector,SD_MONST_IMPS,valid_sectors,&cesta); + TFLEE_MONSTER_CONTEXT fmc; + fmc.last_sector = 0; + fmc.fleeing_mob = m; + labyrinth_find_path(m->sector,65535,SD_MONST_IMPS,valid_sectors,NULL,&fmc); + i=labyrinth_find_path(m->sector,fmc.last_sector,SD_MONST_IMPS,valid_sectors,&cesta,&fmc); for(j=0;j0 && (vls[VLS_POHYB])<15)?1:(vls[VLS_POHYB])/15) +#define AP_MULTIPLIER 15 +#define get_ap(vls) (((vls[VLS_POHYB])>0 && (vls[VLS_POHYB])>3; - if (!(ok_flags[w] & c) && proc(d)) + if (!(ok_flags[w] & c) && (proc==NULL || proc(d, ctx))) { ok_flags[w]|=c; *stk_free++=d | ((stk_cur-stack)<<16); diff --git a/game/inv.c b/game/inv.c index 9f225af..f99e8c3 100644 --- a/game/inv.c +++ b/game/inv.c @@ -447,7 +447,7 @@ int find_item(short *place,int mask) static int lastsector; -static char ValidateSector(word sector) +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) @@ -471,7 +471,7 @@ void push_item(int sect,int pos,short *picked_item) { if (game_extras & EX_RECOVER_DESTROYED_ITEMS) { - labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,ValidateSector,NULL); + labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,ValidateSector,NULL, NULL); push_item(lastsector,viewdir,picked_item); return; } @@ -1281,6 +1281,7 @@ typedef struct t_inv_script } T_INV_SCRIPT; #define INFO_AP -1 +#define INFO_APF -3 #define INFO_EXP -2 #define LINE_STEP 6 #define COL_STEP 8 @@ -1324,7 +1325,8 @@ static T_INV_SCRIPT script[]= {0,37,NULL,0,97,1,0}, {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,9,"%d",INFO_AP,0,2,2}, + {28,9,"%d",INFO_AP,0,2,2}, + {28,9,".%d",INFO_APF,0,2,0}, {17,5,NULL,0,18,1,0}, {17,7,NULL,0,17,1,0}, {17,9,NULL,0,20,1,0}, @@ -1352,9 +1354,12 @@ static int calc_value(int parm,int lenght) l=(human_selected->levellevel-1]-human_selected->exp):0); break; case INFO_AP: - l=get_ap(human_selected->vlastnosti); + l=human_selected->vlastnosti[VLS_POHYB]/AP_MULTIPLIER; break; - } + case INFO_APF: + l=((human_selected->vlastnosti[VLS_POHYB] * 10)/AP_MULTIPLIER) % 10; + break; + } switch(lenght) { case 1:l=(int32_t)((signed char)l);break; @@ -2028,7 +2033,7 @@ static char check_double_wield(int newplace,short item) z2=glob_items[item2-1].zmeny; for(i=0;i<4;i++) { - int chk=(*q1+*q2)*3/4; + int chk=(*q1+*q2)-(human_selected->vlastnosti[VLS_OBRAT]/2); //cim vyssi obratnost tim spis double wield if (*pmana-=k->mge; if ((game_extras & EX_RANDOM_BACKFIRES)!=0) { - labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,get_valid_sector,NULL); + word last_sector = p->sektor; + labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,get_valid_sector,NULL,&last_sector); teleport_target=last_sector; cast(rand()*105/RAND_MAX+(cil*512),p,p-postavy,1); return; diff --git a/game/macros.c b/game/macros.c index a26386d..2cf93ae 100644 --- a/game/macros.c +++ b/game/macros.c @@ -460,25 +460,26 @@ static char monster_in_game(void) return 0; } -static char monster_test; -static char is_monster(word sector) + +static char is_monster(word sector, void *flag) { + char *monster_test = (char *)flag; int m1,m2; m1=mob_map[sector]-1; if (m1>=0) { m2=mobs[m1].next-1; - if (~mobs[m1].vlajky & MOB_MOBILE && (m2<0 || ~mobs[m2].vlajky & MOB_MOBILE)) monster_test=1; + if (~mobs[m1].vlajky & MOB_MOBILE && (m2<0 || ~mobs[m2].vlajky & MOB_MOBILE)) *monster_test=1; } - return !monster_test; + return !*monster_test; } static char monster_in_room(int sector) { - monster_test=0; - is_monster(sector); - if (!monster_test) labyrinth_find_path(sector,65535,SD_MONST_IMPS,is_monster,NULL); + char monster_test=0; + is_monster(sector, &monster_test); + if (!monster_test) labyrinth_find_path(sector,65535,SD_MONST_IMPS,is_monster,NULL, &monster_test); return monster_test; } @@ -650,19 +651,13 @@ static int ma_play_anim(const char *filename,char cls) return 0; } -static char ma_control_mob_control(word sector) - { - sector; - return 1; - } - static void ma_control_mob(int from,int to) { word *path; int m; if (mob_map[from]==0) return; - if (labyrinth_find_path(from,to,SD_MONST_IMPS,ma_control_mob_control,&path)==0) return; + if (labyrinth_find_path(from,to,SD_MONST_IMPS,NULL,&path,NULL)==0) return; m=mob_map[from]-1; send_mob_to(m,path); } diff --git a/game/realgame.c b/game/realgame.c index 47a02f9..bdb9e53 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -18,6 +18,7 @@ #include "globals.h" #include +#include #include @@ -69,6 +70,7 @@ char sekceid[]=""; char datapath; D_ACTION *d_action={NULL}; int end_ptr; +char pass_all_mobs = 0; //cheat make all mobs passable uint8_t cur_group=1; uint8_t group_select=1; char cancel_pass=0; @@ -162,7 +164,7 @@ uint32_t fnv1a_hash(const char *str) { uint32_t hash = 0x01000193; while (*str) { - hash ^= (unsigned char)(*str); + hash ^= (unsigned char)(toupper(*str)); hash *= 0x811C9DC5; str++; } @@ -1559,7 +1561,9 @@ void step_zoom(char smer) mob_map[nsect]=0; } else if (mob_map[nsect] && !nopass) { - if (!battle){ if (!mob_alter(nsect)) return; } + if (!battle){ + if (!pass_all_mobs && !mob_alter(nsect)) return; + } else return; } if (map_sectors[nsect].sector_type==S_LODKA) diff --git a/game/skeldal.c b/game/skeldal.c index f7c2668..4c80ff3 100644 --- a/game/skeldal.c +++ b/game/skeldal.c @@ -1326,7 +1326,7 @@ static void game_big_circle(char enforced) } } for (int i = 0; i=0 && idx < POCET_POSTAV) { + pohyblivost_counter[idx] += h->vlastnosti[VLS_POHYB]; + } +} + + + +int pc_get_actions(THUMAN *h) { + int idx = h- postavy; + if (idx >=0 && idx < POCET_POSTAV) { + return pohyblivost_counter[idx]/AP_MULTIPLIER; + } + return 0; +} + +void pc_use_actions(THUMAN *h, int count) { + int idx = h- postavy; + if (idx >=0 && idx < POCET_POSTAV) { + int useap = count * AP_MULTIPLIER; + useap = MIN(useap, pohyblivost_counter[idx]); + pohyblivost_counter[idx] -= useap; + } + +} + THUMAN *isplayer(int sector,THUMAN *h,char death) { @@ -530,6 +558,7 @@ void zacatek_kola() mobs[i].actions=get_ap(mobs[i].vlastnosti); mobs[i].walk_data=0; } + memset(plr_switcher,0,sizeof(plr_switcher)); for(i=0;ikondice && p->lives && p->inmaphash == current_map_hash) { - p->actions=get_ap(p->vlastnosti); + pc_gain_action(p); + p->actions=pc_get_actions(p); // if (p->actions) autostart_round=0; } else postavy[i].actions=0; @@ -1100,13 +1130,13 @@ void pouzij_zbran(THUMAN *p,int ruka) bott_draw(0); } -static word last_sector; -static char valid_sectors(word sector) +static char valid_sectors(word sector, void *ctx) { int pp; int i; + word *last_sector = (word *)ctx; - last_sector=sector; + *last_sector=sector; if (mob_map[sector]) return 0; //nevyhovujici pp=map_sectors[sector].sector_type; if (pp==S_DIRA || ISTELEPORT(pp)) return 0; @@ -1119,6 +1149,7 @@ static char StrachPostavy(THUMAN *p) { word *cesta; int i; + word last_sector = 0; int wf=weigth_defect(p)+1; @@ -1126,8 +1157,8 @@ static char StrachPostavy(THUMAN *p) cur_group=p->groupnum; for(select_player=0;select_player<6;select_player++) if (postavy+select_player==p) break; bott_draw(0); - labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,valid_sectors,NULL); - labyrinth_find_path(p->sektor,last_sector,SD_PLAY_IMPS,valid_sectors,&cesta); + labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,valid_sectors,NULL,&last_sector); + labyrinth_find_path(p->sektor,last_sector,SD_PLAY_IMPS,valid_sectors,&cesta,&last_sector); if (cesta[0]==0) {free(cesta);return 0;} for (i=0;i<6 && cesta[i] && p->kondice ;i++) { @@ -1237,7 +1268,13 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje wire_presun_postavy(); break; } - case AC_ATTACK:pouzij_zbran(p,p->provadena_akce->data1);break; + case AC_ATTACK:pouzij_zbran(p,p->provadena_akce->data1); + if (p->provadena_akce->data1 == 2 && plr_switcher[p-postavy] == 1) { + prave_hraje--; + neco_v_pohybu = 1; + return; + } + break; case AC_ARMOR:souboje_prezbrojeni(nxt); bott_draw(1); other_draw(); @@ -1799,6 +1836,8 @@ static void zahajit_kolo(char prekvapeni) int counter=5; short w1,w2,dw1,dw2,w; + pc_use_actions(p, pc_get_actions(p)); + while (~map_sides[(sect<<2)+dir].flags & SD_PLAY_IMPS) { int m1,m2; @@ -2047,6 +2086,7 @@ void start_battle() if (!running_battle) { SEND_LOG("(BATTLE) Battle started (monster: %s)",attack_mob!=NULL?attack_mob->name:"(NULL)"); + memset(pohyblivost_counter,0,sizeof(pohyblivost_counter)); poloz_vsechny_predmety(); zacatek_kola(); running_battle=1; diff --git a/platform/sdl/sound.cpp b/platform/sdl/sound.cpp index 7f00de7..97f1300 100644 --- a/platform/sdl/sound.cpp +++ b/platform/sdl/sound.cpp @@ -16,7 +16,7 @@ static SoundMixer<2> sound_mixer; static float master_volume = 1.0; static float sound_effect_volume = 1.0; -static float music_volume = 1.0; +static float music_volume = 0.5; static float base_freq; bool swap_channels = false; static void empty_deleter(const void *) {}