diff --git a/game/automap.c b/game/automap.c index a3410a1..c59b8b5 100644 --- a/game/automap.c +++ b/game/automap.c @@ -556,26 +556,30 @@ void draw_automap(int xr,int yr) { int j,l=-1; - for(j=0;jvlastnosti[VLS_MAXMANA]) y=BARS_YS-p->mana*BARS_YS/p->vlastnosti[VLS_MAXMANA];else y=BARS_YS; if (y<0) y=0; if (y) bar32(x+MANA_S,BARS_S,x+MANA_E,BARS_S+y); - if (p->sektor!=viewsector) trans_bar25(x,0,74,102); + if (p->sektor!=viewsector || p->inmaphash != current_map_hash) trans_bar25(x,0,74,102); set_font(H_FLITT,p->groupnum==cur_group && !battle?SEL_COLOR:barvy_skupin[p->groupnum]); set_aligned_position(x+36,92,1,0,p->jmeno);outtext(p->jmeno); - c[0]=p->groupnum+48;set_aligned_position(x+5,86,0,2,c);outtext(c); - if (cur_mode==MD_INBATTLE) + c[0]=p->inmaphash !=current_map_hash?'-':p->groupnum+48;set_aligned_position(x+5,86,0,2,c);outtext(c); + if (cur_mode==MD_INBATTLE && p->inmaphash == current_map_hash) { char s[20]; signed char dir; @@ -826,34 +826,36 @@ static int draw_basic_sector(int celx, int cely, int sector) { TSTENA *w, *q; int obl; + int tmask = true_seeing?SD_TRUESEE:0; + w = &map_sides[sector * 4]; q = &w[dirs[1]]; obl = GET_OBLOUK(q); if (cely < VIEW3D_Z) { if (q->flags & SD_LEFT_ARC && obl) - show_cel2(celx, cely, ablock(num_ofsets[OBL_NUM] + obl), 0, 0, 1); + show_cel2(celx, cely, ablock(num_ofsets[OBL_NUM] + obl), 0, 0, 1, ghost_walls ); if (q->flags & SD_RIGHT_ARC && q->oblouk & 0x0f) - show_cel2(celx, cely, ablock(num_ofsets[OBL2_NUM] + obl), 0, 0, 2); - if (q->flags & SD_PRIM_VIS && q->prim && !hide_walls) + show_cel2(celx, cely, ablock(num_ofsets[OBL2_NUM] + obl), 0, 0, 2, ghost_walls); + if (q->flags & SD_PRIM_VIS && q->prim) show_cel2(celx, cely, ablock( num_ofsets[MAIN_NUM] + q->prim + (q->prim_anim >> 4)), 0, 0, - 1 + (q->oblouk & SD_POSITION)); + 1 + (q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (q->flags & SD_SEC_VIS && q->sec) { if (q->side_tag & SD_SHIFTUP) { if (cely != 0) { show_cel2(celx, cely - 1, ablock( num_ofsets[MAIN_NUM] + q->sec - + (q->sec_anim >> 4)), 0, 0, 1); + + (q->sec_anim >> 4)), 0, 0, 1, ghost_walls | (q->flags & tmask)); } } else { show_cel2(celx, cely, ablock( num_ofsets[MAIN_NUM] + q->sec + (q->sec_anim >> 4)), q->xsec << 1, - q->ysec << 1, 0); + q->ysec << 1, 0, ghost_walls | (q->flags & tmask)); } } if (q->oblouk & 0x10) @@ -863,13 +865,13 @@ static int draw_basic_sector(int celx, int cely, int sector) { q = &w[dirs[0]]; if (left_shiftup) show_cel(celx, cely, ablock(num_ofsets[LEFT_NUM] + left_shiftup), 0, - 0, 2), left_shiftup = 0; - if (q->flags & SD_PRIM_VIS && q->prim && !hide_walls) + 0, 2, ghost_walls), left_shiftup = 0; + if (q->flags & SD_PRIM_VIS && q->prim ) show_cel(-celx, cely, ablock( num_ofsets[LEFT_NUM] + q->prim + (q->prim_anim >> 4)), 0, 0, - 2 + (q->oblouk & SD_POSITION)); + 2 + (q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (q->flags & SD_SEC_VIS && q->sec) { if (q->side_tag & SD_SHIFTUP) { if (celx != 0) { @@ -881,13 +883,13 @@ static int draw_basic_sector(int celx, int cely, int sector) { show_cel(celx, cely, ablock( num_ofsets[LEFT_NUM] + q->sec - + (q->sec_anim >> 4)), 0, 0, 2); + + (q->sec_anim >> 4)), 0, 0, 2, ghost_walls | (q->flags & tmask)); } else { show_cel(celx, cely, ablock( num_ofsets[LEFT_NUM] + q->sec + (q->sec_anim >> 4)), q->xsec << 1, - q->ysec << 1, 0); + q->ysec << 1, 0, ghost_walls | (q->flags & tmask)); } } } @@ -895,13 +897,13 @@ static int draw_basic_sector(int celx, int cely, int sector) { q = &w[dirs[2]]; if (right_shiftup) show_cel(celx, cely, ablock(num_ofsets[RIGHT_NUM] + right_shiftup), - 0, 0, 3), right_shiftup = 0; - if (q->flags & SD_PRIM_VIS && q->prim && !hide_walls) + 0, 0, 3, ghost_walls), right_shiftup = 0; + if (q->flags & SD_PRIM_VIS && q->prim ) show_cel(celx, cely, ablock( num_ofsets[RIGHT_NUM] + q->prim + (q->prim_anim >> 4)), 0, 0, - 3 + (q->oblouk & SD_POSITION)); + 3 + (q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (q->flags & SD_SEC_VIS && q->sec) { if (q->side_tag & SD_SHIFTUP) { if (celx != 0) @@ -912,13 +914,13 @@ static int draw_basic_sector(int celx, int cely, int sector) { show_cel(celx, cely, ablock( num_ofsets[RIGHT_NUM] + q->sec - + (q->sec_anim >> 4)), 0, 0, 3); + + (q->sec_anim >> 4)), 0, 0, 3, ghost_walls | (q->flags & tmask)); } else { show_cel(celx, cely, ablock( num_ofsets[RIGHT_NUM] + q->sec + (q->sec_anim >> 4)), - 500 - (q->xsec << 1), q->ysec << 1, 1); + 500 - (q->xsec << 1), q->ysec << 1, 1, ghost_walls | (q->flags & tmask)); } } @@ -929,7 +931,7 @@ static int draw_basic_sector(int celx, int cely, int sector) { static int draw_lodku(int celx,int cely) { if (cely==0) return 1; - show_cel2(celx,cely-1,ablock(H_LODKA0+(global_anim_counter & 7)),250,80,0); + show_cel2(celx,cely-1,ablock(H_LODKA0+(global_anim_counter & 7)),250,80,0,0); return 0; } @@ -946,6 +948,7 @@ int p_positions_y[5]={32,32,-32,-32,0}; void draw_players(int sector,int dir,int celx,int cely) { + if (map_coord[sector].flags & MC_DPLAYER) { int i; @@ -956,7 +959,7 @@ void draw_players(int sector,int dir,int celx,int cely) memset(freep,0,sizeof(freep)); for(i=0,pp=0;isektor==sector && ((!p->lives && p->groupnum==0) || p->sektor!=viewsector)) + if ((p=postavy+i)->sektor==sector && p->inmaphash == current_map_hash && ((!p->lives && p->groupnum==0) || p->sektor!=viewsector)) { pp++; d=(p->direction-dir)&0x3; @@ -996,33 +999,36 @@ int draw_sloup_sector(int celx,int cely,int sector) TSTENA *w,*q; int obl; + int tmask = true_seeing?SD_TRUESEE:0; + + w=&map_sides[sector*4]; q=&w[dirs[1]]; obl=GET_OBLOUK(q); if (q->flags & SD_LEFT_ARC && q->oblouk) - show_cel2(celx,cely,ablock(num_ofsets[OBL_NUM]+obl),0,0,1); + show_cel2(celx,cely,ablock(num_ofsets[OBL_NUM]+obl),0,0,1, ghost_walls); if (q->flags & SD_RIGHT_ARC && q->oblouk) - show_cel2(celx,cely,ablock(num_ofsets[OBL2_NUM]+obl),0,0,2); - if (q->flags & SD_PRIM_VIS && q->prim && !hide_walls) - show_cel2(celx,cely,ablock(num_ofsets[MAIN_NUM]+q->prim+(q->prim_anim>>4)),0,0,1+(q->oblouk & SD_POSITION)); + show_cel2(celx,cely,ablock(num_ofsets[OBL2_NUM]+obl),0,0,2, ghost_walls); + if (q->flags & SD_PRIM_VIS && q->prim ) + show_cel2(celx,cely,ablock(num_ofsets[MAIN_NUM]+q->prim+(q->prim_anim>>4)),0,0,1+(q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (celx<=0) { q=&w[dirs[0]]; - if (q->flags & SD_PRIM_VIS && q->prim && !hide_walls) - show_cel(-celx,cely,ablock(num_ofsets[LEFT_NUM]+q->prim+(q->prim_anim>>4)),0,0,2+(q->oblouk & SD_POSITION)); + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel(-celx,cely,ablock(num_ofsets[LEFT_NUM]+q->prim+(q->prim_anim>>4)),0,0,2+(q->oblouk & SD_POSITION), ghost_walls| (q->flags & tmask)); } if (celx>=0) { q=&w[dirs[2]]; - if (q->flags & SD_PRIM_VIS && q->prim && !hide_walls) - show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->prim+(q->prim_anim>>4)),0,0,3+(q->oblouk & SD_POSITION)); + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->prim+(q->prim_anim>>4)),0,0,3+(q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); } q=&w[dirs[1]]; if (q->flags & SD_SEC_VIS && q->sec && cely!=0) { if (q->flags & SD_SPEC) - show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),0,0,2); + show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),0,0,2, ghost_walls| (q->flags & tmask)); else - show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),(q->xsec<<1)+celx*(points[0][0][cely].x-points[0][0][cely-1].x)/2,q->ysec<<1,0); + show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),(q->xsec<<1)+celx*(points[0][0][cely].x-points[0][0][cely-1].x)/2,q->ysec<<1,0, ghost_walls| (q->flags & tmask)); } return 0; } @@ -1041,9 +1047,9 @@ void swap_truesee(int ss) void draw_sector(int celx,int cely,int s) { - int ss; - ss=s<<2; - if (true_seeing) swap_truesee(ss); +// int ss; + //ss=s<<2; +// if (true_seeing) swap_truesee(ss); switch (map_sectors[s].sector_type) { case S_SSMRT: @@ -1062,7 +1068,7 @@ void draw_sector(int celx,int cely,int s) draw_placed_items_normal(celx,cely,s,viewdir); break; } - if (true_seeing) swap_truesee(ss); +// if (true_seeing) swap_truesee(ss); } void back_clear(int celx,int color) @@ -1279,10 +1285,10 @@ void debug_print() static char indx=50; static int counter=0; - sprintf(s,"battle: %d waiting: %d lhit: %3d ldef: %3d dostal: %3d magic: %3d lives: %3d wpn: %d", + sprintf(s,"battle: %d waiting: %d lhit: %3d ldef: %3d hit: %3d magic-hit: %3d lives: %3d weapon: %d", battle, neco_v_pohybu, dhit, ddef, ddostal, dmzhit, dlives, vybrana_zbran ); trans_bar(0,17,640,15,0); - position(0,17);set_font(H_FBOLD,0x3ff); + position(0,17);set_font(H_FONT6,0x3ff); if (debug_text!=NULL) { outtext(debug_text); diff --git a/game/clk_map.c b/game/clk_map.c index 165fb21..b2b7791 100644 --- a/game/clk_map.c +++ b/game/clk_map.c @@ -256,7 +256,7 @@ char start_invetory(int id,int xa,int ya,int xr,int yr) { i=group_sort[i]; p=&postavy[i]; - if (p->used) + if (p->used && p->inmaphash == current_map_hash) { if (ms_last_event.event_type & 0x2) { diff --git a/game/console.c b/game/console.c index ed188b4..2ca8f2f 100644 --- a/game/console.c +++ b/game/console.c @@ -450,7 +450,8 @@ static PARSED_COMMAND parse_command(const char *cmd) { return ret; } -extern int hide_walls; +extern int ghost_walls; +extern int nofloors; static int process_on_off_command(const char *cmd, char on) { if (stricmp(cmd, "inner-eye") == 0) { @@ -473,8 +474,24 @@ static int process_on_off_command(const char *cmd, char on) { cur_group=on?10:postavy[0].groupnum; return 1; } - if (stricmp(cmd, "hide-walls") == 0) { - hide_walls = on; + if (stricmp(cmd, "ghost-walls") == 0) { + ghost_walls = on; + return 1; + } + if (stricmp(cmd, "true-seeing") == 0) { + true_seeing = on; + return 1; + } + if (stricmp(cmd, "walking-in-air") == 0) { + nofloors = on; + return 1; + } + if (stricmp(cmd, "enemy-insight") == 0) { + show_mob_info = on; + return 1; + } + if (stricmp(cmd, "enemy-walk-diagonal") == 0) { + game_extras = on?(game_extras | EX_WALKDIAGONAL):(game_extras & ~EX_WALKDIAGONAL); return 1; } return 0; @@ -554,10 +571,19 @@ static int process_with_params(const char *cmd, const char *args) { console_add_line(args); return 1; } + if (stricmp(cmd, "speed") == 0) { + long v = strtol(args, NULL, 10); + if (v > 0) timerspeed_val = v; + return v > 0; + } return 0; } static int process_command(PARSED_COMMAND cmd) { + if (cmd.command == NULL) { + console_add_line(""); + return 0; + } int onoff = -1; if (cmd.args) { if (stricmp(cmd.args, "on") == 0) onoff = 1; diff --git a/game/dialogy.c b/game/dialogy.c index 04a0140..1a64970 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) @@ -988,6 +988,32 @@ char drop_character() static char dead_players=0; + char is_player_near(int sector, THUMAN *p, int exclude_dir) { + if (sector == p->sektor) return 1; + for (int i = 0; i < 4; ++i) if (i != exclude_dir) { + if (map_sectors[sector].step_next[i] == p->sektor + && (map_sides[sector * 4 + i].flags & SD_PLAY_IMPS) == 0) return 1; + } + return 0; +} + +char can_select_player(THUMAN *p, char select_dead, char select_far) { + if (select_dead) { + if (p->used && p->lives == 0 && ( + p->sektor == 0 || p->sektor == viewsector)) return 1; + } else { + int side = (viewsector << 2) + viewdir; + if (p->used && p->lives != 0 && (select_far || + (p->sektor == viewsector + || ((map_sides[side].flags & SD_PLAY_IMPS) == 0 + && is_player_near(map_sectors[viewsector].step_next[viewdir], p, viewdir) + + )))) + return 1; + } + return 0; +} + static char ask_who_proc(int id,int xa,int ya,int xr,int yr) { { @@ -1007,8 +1033,7 @@ static char ask_who_proc(int id,int xa,int ya,int xr,int yr) { i=group_sort[i]; p=&postavy[i]; - if (p->used && ((p->lives!=0) ^ (dead_players))) - if (p->sektor==viewsector) + if (can_select_player(p,dead_players,0)) { selected_player=i; exit_wait=1; @@ -1139,7 +1164,7 @@ static void dark_screen(int time,int gtime) showview(0,0,0,0); while (get_timer_value()used && h->lives) + for(i=0,h=postavy;iused && h->lives && h->inmaphash == current_map_hash) { z=h->vlastnosti[VLS_HPREG]*gtime;z+=h->lives; if (z>h->vlastnosti[VLS_MAXHIT]) {z=h->vlastnosti[VLS_MAXHIT];h->lives=z;} @@ -1156,10 +1181,10 @@ static char najist_postavy(int cena) int i,s=0; THUMAN *h=postavy; - for(i=0;iused && h->sektor==viewsector && h->lives) s=s+cena; + for(i=0;iused && h->sektor==viewsector && h->lives && h->inmaphash != current_map_hash) s=s+cena; if (s>money) return 1; money-=s; - for(i=0,h=postavy;iused && h->sektor==viewsector && h->lives) + for(i=0,h=postavy;iused && h->sektor==viewsector && h->lives && h->inmaphash != current_map_hash) { h->jidlo=MAX_HLAD(h); h->voda=MAX_ZIZEN(h); @@ -1172,7 +1197,7 @@ static char isall() THUMAN *h=postavy; int i; - for(i=0,h=postavy;isektor!=viewsector && h->used && h->lives) return 0; + for(i=0,h=postavy;isektor!=viewsector && h->used && h->lives && h->inmaphash == current_map_hash) return 0; return 1; } diff --git a/game/enemy.c b/game/enemy.c index 02dbb7c..95a5361 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -42,6 +42,7 @@ int mob_dostal_pocet; char folow_mode=0; char folow_mob; +char show_mob_info = 0; char mob_go_x[]={128,255,128,0}; char mob_go_y[]={0,128,255,128}; @@ -284,7 +285,7 @@ static char pick_item_corpse(TMOB *m,char query) { int i; THUMAN *h; //najdi mezi hraci mrtvolu ktera tam lezi - for(i=0,h=postavy;ilives && h->used && h->sektor==sector) + for(i=0,h=postavy;ilives && h->used && h->inmaphash == current_map_hash &&h->sektor==sector) { int i; //podivej se ji do inventare.... for(i=0;iprsteny[i]) p=&h->prsteny[i]; @@ -545,7 +546,7 @@ int q_vidis_postavu(int sector,int dir,TMOB *p,int *otocit_se,char ret) xs=map_coord[sector].x-map_coord[postavy[i].sektor].x; ys=map_coord[sector].y-map_coord[postavy[i].sektor].y; d=MAX(abs(xs),abs(ys)); - if (d<=p->dohled && (!(ps->vlastnosti[VLS_KOUZLA] & SPL_INVIS)||p->vlajky & MOB_SENSE) && ps->used && ps->lives) + if (d<=p->dohled && (!(ps->vlastnosti[VLS_KOUZLA] & SPL_INVIS)||p->vlajky & MOB_SENSE) && ps->used && ps->lives && ps->inmaphash == current_map_hash) switch(dir) { case 0:ok=ys>=0;break; @@ -893,19 +894,29 @@ void krok_moba(TMOB *p) } } -static char get_view_mirror=0; -int get_view(TMOB *p,int dirmob,int action,int curdir) +typedef struct enemy_face_tag { + int pos; + int face; + int mirror; +} TENEMY_FACE; + + +TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir) { + + TENEMY_FACE ret; int view;int pos; int xs,ys; - get_view_mirror=0; + ret.mirror = 0; if (action==MOB_ATTACK) pos=4; else if (action==MOB_TO_HIT) pos=5; else if (action==MOB_DEATH) { - return 1; + ret.pos = 0; + ret.face = 0; + return ret; } else { @@ -929,10 +940,12 @@ int get_view(TMOB *p,int dirmob,int action,int curdir) } } } - if (pos==3) get_view_mirror=pos=1; + if (pos==3) ret.mirror=pos=1; if (p->anim_counter==-1) view=pos*16; else view=pos*16+(p->anim_counter % p->anim_counts[pos])+1; - return view; + ret.face = view; + ret.pos = pos; + return ret; } void get_pos(int x,int y,int *xpos,int *ypos,int dir) @@ -1000,12 +1013,78 @@ static void CheckMobStoned(int num) } +static void fill_drw_enemy_struct(TMOB *m, DRW_ENEMY *enm, char *buff, int curdir) { + if (!show_mob_info) { + enm->more_info = NULL; + return; + } + char flag_buff[100] = ""; + char strategy_buff[100] = ""; + const char *strategies[] = { + "WALK","WATCH","LISTEN","BIG","GUARD","PICK","PICKING","ROGUE" + }; + const char *flags[] = { + "BATTLE","PASSABLE","SENS","MOB","RESPWN","CAST","SNDLP","LIVE" + }; + const char *modes[] = {"NONE","CAST","FLEE","ATTACK"}; + + const char *actions[] = { + "STANDFWD","STANDLEFT","STANDBACK","STANDRIGHT","STANDLEFTMIRR", + "WALKFWD","WALKLEFT","WALKBACK","WALKRIGHT","WALKLEFTMIRR", + "ATTACK","ATTACKMIRR","INPAIN","INPAINMIRR","ERR"}; + + TENEMY_FACE fc = get_enemy_face(m,m->dir,m->anim_phase,curdir); + int action = countof(actions)-1; + int stand = (fc.face & 0xF) == 0; + if (fc.pos < 4) { + action = (fc.mirror?4:fc.pos) + (stand?0:5); + } else { + action = ((fc.pos - 4)*2+(fc.mirror?1:0))+10; + } + + for (int i = 0; i < 8; i++) { + if (m->stay_strategy & (1<vlajky & (1<name, + actions[action], + m->walk_data, + m->dohled, + m->dosah, + m->dostal, + modes[(uint8_t)m->mode], + strategy_buff, + flag_buff, + mob_paths[m - mobs]!=NULL?"YES":"NO" + ); + enm->more_info = buff; +} + + void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup) { TMOB *p,*q; - int view,vw; - int view2,vw2; + TENEMY_FACE view; + int vw; + TENEMY_FACE view2; + int vw2; DRW_ENEMY drw1,drw2; + char buff[256], buff2[256]; set_font(H_FLITT5,RGB555(31,31,0)); CheckMobStoned(num-MOB_START); @@ -1013,43 +1092,54 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup) shiftup|=(p->stay_strategy & MOB_BIG); get_pos(p->locx-128,p->locy-128,&drw1.posx,&drw1.posy,curdir); - view=get_view(p,p->dir,p->anim_phase,curdir); - vw=p->cislo_vzoru+view+monster_block; - if (p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) {drw1.txtr=NULL;vw=0;}else drw1.txtr=ablock(vw); + view=get_enemy_face(p,p->dir,p->anim_phase,curdir); + vw=p->cislo_vzoru+view.face+monster_block; + if ((p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) { + drw1.txtr = NULL; + vw = 0; + } else { + drw1.txtr = ablock(vw); + } drw1.celx=celx; drw1.cely=cely; - drw1.mirror=get_view_mirror; - drw1.adjust=p->adjusting[view]; + drw1.mirror=view.mirror; + drw1.adjust=p->adjusting[view.face]; drw1.shiftup=shiftup; drw1.num=p->lives; drw1.palette=mob_select_palette(p); drw1.stoned= (p->vlastnosti[VLS_KOUZLA] & SPL_STONED)!=0; see_monster|=(~p->vlajky & MOB_PASSABLE); + fill_drw_enemy_struct(p, &drw1, buff, curdir); if (p->next) { CheckMobStoned(p->next-MOB_START); q=&mobs[p->next-MOB_START]; get_pos(q->locx-128,q->locy-128,&drw2.posx,&drw2.posy,curdir); - view2=get_view(q,q->dir,q->anim_phase,curdir); - vw2=view2+q->cislo_vzoru+monster_block; + view2=get_enemy_face(q,q->dir,q->anim_phase,curdir); + vw2=view2.face+q->cislo_vzoru+monster_block; drw2.shiftup=shiftup; drw2.celx=celx; drw2.cely=cely; alock(vw); alock(vw+6*16+5); - if (q->vlastnosti[VLS_KOUZLA] & SPL_INVIS) {drw2.txtr=NULL;vw2=0;}else drw2.txtr=ablock(vw2); - drw2.mirror=get_view_mirror; + if ((q->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) { + drw2.txtr = NULL; + vw2 = 0; + } else { + drw2.txtr = ablock(vw2); + } + drw2.mirror=view2.mirror; alock(vw2); alock(vw2+6*16+5); - drw2.adjust=q->adjusting[view2]; + drw2.adjust=q->adjusting[view2.face]; drw2.num=q->lives; drw2.palette=mob_select_palette(q); drw2.stoned=(q->vlastnosti[VLS_KOUZLA] & SPL_STONED)!=0; see_monster|=(~q->vlajky & MOB_PASSABLE); + fill_drw_enemy_struct(q, &drw2, buff2, curdir); } else { - view2=-1; draw_enemy(&drw1); return; } @@ -1433,7 +1523,7 @@ void mobs_hit(TMOB *p) for(i=0;iused && p->sektor==asect && p->lives) pocet++; + if (p->used && p->sektor==asect && p->lives && p->inmaphash == current_map_hash) pocet++; } if (!pocet) abort(); obet=1+rnd(pocet); @@ -1443,7 +1533,7 @@ void mobs_hit(TMOB *p) i++; if (i>=POCET_POSTAV) i=0; p=&postavy[i]; - if (p->used && p->sektor==asect && p->lives) obet--; + if (p->used && p->sektor==asect && p->lives && p->inmaphash == current_map_hash) obet--; } h=&postavy[i]; if (h->utek) @@ -1864,7 +1954,7 @@ char flee_monster_zac(TMOB *m) int i,j; word *cesta,*c,cntr; for(j=0;jused && p->lives && p->sektor==sect) + if (p->used && p->lives && p->sektor==sect && p->inmaphash == current_map_hash) { if (((m->vlajky & MOB_CASTING) && get_spell_track(m->casting))|| m->stay_strategy & MOB_ROGUE) {stop_all_mobs_on_sector(m->sector);smeruj_moba(m,0);} @@ -1942,7 +2032,7 @@ char akce_moba_zac(TMOB *m) { THUMAN *p=&postavy[j]; - if (p->used && p->lives && p->sektor==sect && !(p->vlastnosti[VLS_KOUZLA] & SPL_INVIS)) + if (p->used && p->lives && p->inmaphash == current_map_hash &&p->sektor==sect && !(p->vlastnosti[VLS_KOUZLA] & SPL_INVIS)) { m->dir=i; stop_mob(m); diff --git a/game/engine1.c b/game/engine1.c index c59a670..243fe09 100644 --- a/game/engine1.c +++ b/game/engine1.c @@ -42,9 +42,11 @@ int yreq; int last_scale; char secnd_shade=1; -void sikma_zleva(void); +void sikma_zleva_norm(void); +void sikma_zleva_alpha(void); //#pragma aux sikma_zleva parm modify [EAX EBX ECX EDX ESI EDI] -void sikma_zprava(void); +void sikma_zprava_norm(void); +void sikma_zprava_alpha(void); //#pragma aux sikma_zprava parm modify [EAX EBX ECX EDX ESI EDI] /*void zooming_dx(void *source,void *target,void *background,void *xlat,int32_t xysize); //#pragma aux zooming_dx parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] @@ -102,7 +104,7 @@ void (*zooming)(void *source,int32_t target,word *background,void *xlat,int32_t void (*turn)(int32_t lbuf,void *src1,void *src2,int size1); word *GetBuffer2nd(); word *background; -char debug=0,nosides=0,nofloors=0,drwsit=0,show_names=0,show_lives=0; +char nofloors=0,show_names=0,show_lives=0; /*void zooming1(void *source,int32_t target,word *background,void *xlat,int32_t xysize) @@ -577,7 +579,7 @@ void turn_right() */ } -void show_cel(int celx,int cely,const void *stena,int xofs,int yofs,char rev) +void show_cel(int celx,int cely,const void *stena,int xofs,int yofs,char rev, int alpha) { T_INFO_X_3D *x3d,*x0d; T_INFO_Y *yd,*yp; @@ -646,11 +648,16 @@ void show_cel(int celx,int cely,const void *stena,int xofs,int yofs,char rev) zoom.ycount=realsy+1; zoom.xmax=realsx; zoom.line_len=2*scr_linelen2; - if (rev) sikma_zprava(); else sikma_zleva(); + if (alpha) { + if (rev) sikma_zprava_alpha(); else sikma_zleva_alpha(); + } else { + if (rev) sikma_zprava_norm(); else sikma_zleva_norm(); + } + } -void show_cel2(int celx,int cely,const void *stena,int xofs,int yofs,char rev) +void show_cel2(int celx,int cely,const void *stena,int xofs,int yofs,char rev, int alpha) { T_INFO_X *x3d; T_INFO_Y *yd; @@ -713,9 +720,13 @@ void show_cel2(int celx,int cely,const void *stena,int xofs,int yofs,char rev) zoom.ycount=realsy+1; zoom.xmax=realsx; zoom.line_len=scr_linelen2*2; - if (rev==2) sikma_zprava(); else sikma_zleva(); + if (alpha) { + if (rev==2) sikma_zprava_alpha(); else sikma_zleva_alpha(); + } else { + if (rev==2) sikma_zprava_norm(); else sikma_zleva_norm(); } + } void draw_floor_ceil(int celx,int cely,char f_c,const void *txtr) @@ -1219,6 +1230,7 @@ void set_lclip_rclip(int celx,int cely,int lc,int rc) } } + void draw_enemy(DRW_ENEMY *drw) { int x,y,lx,sd; @@ -1284,17 +1296,25 @@ void draw_enemy(DRW_ENEMY *drw) if (show_lives) { char s[25]; + int ly = y + SCREEN_OFFLINE - last_scale * 5 / 6; RedirectScreenBufferSecond(); sprintf(s, "%d", drw->num); sd = text_width(s) / 2; if (lx - sd > 0 && lx + sd < 639) { - int ly = y + SCREEN_OFFLINE - last_scale * 5 / 6; trans_bar(lx - sd - 5, ly - 10, sd * 2 + 10, 10, 0); set_aligned_position(lx, ly, 1, 2, s); outtext(s); } RestoreScreen(); } + if (drw->more_info && x > 0 && lx < 639) { + int ly = y + SCREEN_OFFLINE - last_scale * 9 / 12; + RedirectScreenBufferSecond(); + position(x, ly); + outtext_w_nl(drw->more_info); + RestoreScreen(); + } + } void draw_player( const short *txtr,int celx,int cely,int posx,int posy,int adjust, const char *name) diff --git a/game/engine1.h b/game/engine1.h index bd7abcc..5db3ce8 100644 --- a/game/engine1.h +++ b/game/engine1.h @@ -29,9 +29,9 @@ void general_engine_init(void); void draw_floor_ceil(int celx,int cely,char f_c,const void *txtr); -void show_cel2(int celx,int cely,const void *stena,int xofs,int yofs,char rev); +void show_cel2(int celx,int cely,const void *stena,int xofs,int yofs,char rev, int alpha); //zobrazi primou stenu ktera lezi pred nebo napravo od pozorovatele -void show_cel(int celx,int cely,const void *stena,int xofs,int yofs,char rev); +void show_cel(int celx,int cely,const void *stena,int xofs,int yofs,char rev, int alpha); void turn_left(void); void turn_right(void); void zooming_backward(const word *background); @@ -118,6 +118,7 @@ extern word *buffer_2nd; extern char show_names; extern char show_lives; extern char secnd_shade; +extern char show_mob_info; typedef short palette_t[256]; diff --git a/game/engine2.c b/game/engine2.c index 3267827..b5f2dae 100644 --- a/game/engine2.c +++ b/game/engine2.c @@ -10,150 +10,70 @@ typedef ZOOMINFO tzoom; extern ZOOMINFO zoom; extern word *screen; -void sikma_zleva(void) -{ - - int32_t scr_linelen2 = GetScreenPitch(); - word *scr = (word *)zoom.startptr; - const word *palette = (word *)zoom.palette; - word cy = zoom.ycount; - const unsigned char *pixmap = zoom.texture; - const short *ytable = zoom.ytable; - while (cy) { - const int32_t *xtable = zoom.xtable; - word cx = zoom.xmax; - word *scr_iter = scr; - const unsigned char *pixmap_iter = pixmap; - while (cx > 0) { - unsigned char pb = *pixmap_iter++; - pixmap_iter+=*xtable; - xtable++; - if (pb == 1) break; - if (pb != 0) *scr_iter = palette[pb]; - scr_iter++; - cx--; - } - pixmap+=zoom.texture_line*(*ytable); - ytable++; - scr-=scr_linelen2; - cy--; - } - - - - /* - - - __asm - { - mov edi,zoom ;nacti ukazatel do obrazovky - mov ebx,[zoom]tzoom.palette ;ukazatel na paletu - mov cx,short ptr [zoom]tzoom.ycount ;velikost textury na y - shl ecx,16 ;vloz do horni pulky ecx - mov esi,[zoom]tzoom.texture ;nacti ukazatel na texturu - skzl3: mov edx,[zoom]tzoom.xtable ;nacti ukazetel na zvetsovaci tabulku x - push esi ;uchovej esi - push edi ;uchovej edi - mov cx,[zoom]tzoom.xmax - skzl1: xor eax,eax ;vynuluj eax pro spravny vypocet - lodsb ;nacti bod - add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x - add edx,4 ;posun se v tabulce x o dalsi polozku - or al,al ;test bodu na nulu - jz skz1 ;preskoc transparetni barvu - cmp al,1 ;test bodu na jedna - jz skz2 ;ukonci kresleni linky pokud narazi na 1 - mov ax,[eax*2+ebx] ;konverze barvy podle palety - mov [edi],ax ;nakresli bod na obrazovce - skz1: add edi,2 ;dalsi pozice - dec cx - jnz skzl1 ;opakuj dokola - skz2: pop edi ;obnov edi - pop esi ;obnov esi - mov edx,[zoom]tzoom.ytable ;vyzvedni ukazatel na ytable - mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu - or cx,cx - jz skzskp - skzl2: add esi,[zoom]tzoom.texture_line ;posun o jednu pozici - dec cx ;sniz citac - jnz skzl2 ;dokud neni nula - skzskp:add edx,2 ;dalsi hodnota v tabulce - mov [zoom]tzoom.ytable,edx ;uloaz na puvodni misto - sub edi,[zoom]tzoom.line_len ;odecti tolik, kolik odpovida lince na obrazovce - sub ecx,10000h ;sniz horni pulku ecx o jedna - jnz skzl3 ;opakuj dokud neni nula - }*/ +#define SIKMA_STENA(suffx, op) \ +void sikma_zleva_##suffx(void) \ +{ \ + \ + int32_t scr_linelen2 = GetScreenPitch(); \ + word *scr = (word *)zoom.startptr; \ + const word *palette = (word *)zoom.palette; \ + word cy = zoom.ycount; \ + const unsigned char *pixmap = zoom.texture; \ + const short *ytable = zoom.ytable; \ + while (cy) { \ + const int32_t *xtable = zoom.xtable; \ + word cx = zoom.xmax; \ + word *scr_iter = scr; \ + const unsigned char *pixmap_iter = pixmap; \ + while (cx > 0) { \ + unsigned char pb = *pixmap_iter++; \ + pixmap_iter+=*xtable; \ + xtable++; \ + if (pb == 1) break; \ + if (pb != 0) op; \ + scr_iter++; \ + cx--; \ + } \ + pixmap+=zoom.texture_line*(*ytable); \ + ytable++; \ + scr-=scr_linelen2; \ + cy--; \ + } \ +} \ +void sikma_zprava_##suffx(void) \ +{ \ + int32_t scr_linelen2 = GetScreenPitch(); \ + word *scr = (word *)zoom.startptr; \ + const word *palette = (word *)zoom.palette; \ + word cy = zoom.ycount; \ + const unsigned char *pixmap = zoom.texture; \ + const short *ytable = zoom.ytable; \ + while (cy) { \ + const int32_t *xtable = zoom.xtable; \ + word cx = zoom.xmax; \ + word *scr_iter = scr; \ + const unsigned char *pixmap_iter = pixmap; \ + while (cx > 0) { \ + unsigned char pb = *pixmap_iter++; \ + pixmap_iter+=*xtable; \ + xtable++; \ + if (pb == 1) break; \ + if (pb != 0) op; \ + scr_iter--; \ + cx--; \ + } \ + pixmap+=zoom.texture_line*(*ytable); \ + ytable++; \ + scr-=scr_linelen2; \ + cy--; \ + } \ } -void sikma_zprava(void) -{ - int32_t scr_linelen2 = GetScreenPitch(); - word *scr = (word *)zoom.startptr; - const word *palette = (word *)zoom.palette; - word cy = zoom.ycount; - const unsigned char *pixmap = zoom.texture; - const short *ytable = zoom.ytable; - while (cy) { - const int32_t *xtable = zoom.xtable; - word cx = zoom.xmax; - word *scr_iter = scr; - const unsigned char *pixmap_iter = pixmap; - while (cx > 0) { - unsigned char pb = *pixmap_iter++; - pixmap_iter+=*xtable; - xtable++; - if (pb == 1) break; - if (pb != 0) *scr_iter = palette[pb]; - scr_iter--; - cx--; - } - pixmap+=zoom.texture_line*(*ytable); - ytable++; - scr-=scr_linelen2; - cy--; - } -/* - __asm - { - mov edi,zoom ;nacti ukazatel do obrazovky - mov ebx,[zoom]tzoom.palette ;ukazatel na paletu - mov cx,short ptr [zoom]tzoom.ycount ;velikost textury na y - shl ecx,16 ;vloz do horni pulky ecx - mov esi,[zoom]tzoom.texture ;nacti ukazatel na texturu -skzp3: mov edx,[zoom]tzoom.xtable ;nacti ukazetel na zvetsovaci tabulku x - push esi ;uchovej esi - push edi ;uchovej edi - mov cx,[zoom]tzoom.xmax -skzp1: xor eax,eax ;vynuluj eax pro spravny vypocet - lodsb ;nacti bod - add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x - add edx,4 ;posun se v tabulce x o dalsi polozku - or al,al ;test bodu na nulu - jz skz3 ;preskoc transparetni barvu - cmp al,1 ;test bodu na jedna - jz skz4 ;ukonci kresleni linky pokud narazi na 1 - mov ax,[eax*2+ebx] ;konverze barvy podle palety - mov [edi],ax ;nakresli bod na obrazovce -skz3: sub edi,2 ;dalsi pozice - dec cx - jnz skzp1 ;opakuj dokola -skz4: pop edi ;obnov edi - pop esi ;obnov esi - mov edx,[zoom]tzoom.ytable ;vyzvedni ukazatel na ytable - mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu - or cx,cx - jz skpskp -skzp2: add esi,[zoom]tzoom.texture_line ;posun o jednu pozici - dec cx ;sniz citac - jnz skzp2 ;dokud neni nula -skpskp: add edx,2 ;dalsi hodnota v tabulce - mov [zoom]tzoom.ytable,edx ;uloaz na puvodni misto - sub edi,[zoom]tzoom.line_len ;odecti tolik, kolik odpovida lince na obrazovce - sub ecx,10000h ;sniz horni pulku ecx o jedna - jnz skzp3 ;opakuj dokud neni nula - }*/ -} +SIKMA_STENA(norm,*scr_iter = palette[pb]) +SIKMA_STENA(alpha,*scr_iter = BLEND_PIXELS(*scr_iter, palette[pb])) + + //; void fcdraw(const void *source,void *target, const void *table) //#pragma aux fcdraw parm [EDX][EBX][EAX] modify [ECX ESI EDI]; @@ -633,7 +553,7 @@ void enemy_draw(const void *src,void *trg,int shade,int scale,int maxspace,int c int ofs = ytable[yiter]; unsigned char *row = picdata+ofs; while (xiter < clipr && xtable[xiter] >= 0 ) { - int xpos = xiter; + int xpos = xiter-clipl; unsigned char p = row[xtable[xiter]]; if (p != 0) { if (p == 1) screen[xpos] = (screen[xpos] & 0x7BDE) >> 1; diff --git a/game/gamesave.c b/game/gamesave.c index 5cdd72e..7d48131 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -484,6 +484,7 @@ int load_map_state() //obnovuje stav mapy; nutno volat po zavolani load_map; res|=load_vyklenky(fsta); res|=load_all_fly(fsta); res|=load_enemy_paths(fsta); + err: SEND_LOG("(SAVELOAD) State of current map loaded (err:%d)",res); temp_storage_close_rd(fsta); diff --git a/game/globals.h b/game/globals.h index 6c38124..84e9452 100644 --- a/game/globals.h +++ b/game/globals.h @@ -613,6 +613,7 @@ extern int bgr_handle; //cislo handle k obrazku pozadi; extern char enable_glmap; //povoluje globalni mapu; extern int charmin; extern int charmax; +extern uint32_t current_map_hash; extern int autoopenaction; extern int autoopendata; @@ -971,6 +972,7 @@ typedef struct thuman int jidlo; //max 25000 //pocet kol o hladu zbyvajicich int voda; //max 20000 //pocet kol o zizny zbyvajicich struct thuman *demon_save; //ukazatel na postavu ulozenou behem kouzla demon + uint32_t inmaphash; //hash nazvu mapy, kde se postavy nachazi }THUMAN; extern TITEM *glob_items; //tabulka predmetu @@ -1792,5 +1794,11 @@ void draw_console_window(void); void console_show(char show); char console_is_visible(void); +char *map_hash_to_string_impl(char *c, uint32_t h, int sz); +#define map_hash_to_string(h) (map_hash_to_string_impl((char *)alloca(31), h, 30)) +const char *find_map_from_hash_impl(char *c, uint32_t h, int sz); +#define find_map_from_hash(h) (find_map_from_hash_impl((char *)alloca(31), h, 30)) +char can_select_player(THUMAN *p, char select_dead, char select_far); + //extras #include "extras.h" diff --git a/game/globmap.c b/game/globmap.c index 417ae0a..b0aaefa 100644 --- a/game/globmap.c +++ b/game/globmap.c @@ -399,7 +399,7 @@ static void do_script(void) static int found_place=0; - +/* static char flp_validate2(word sector) { TMOB *m; @@ -416,7 +416,7 @@ static char flp_validate2(word sector) if (c==S_DIRA || ISTELEPORT(c) || c==S_LAVA || c==S_VODA ) return 0; return 1; } - +*/ static char flp_validate(word sector) { TMOB *m; @@ -454,8 +454,7 @@ static int select_mode = 0; static char load_index_map(int index) { TMA_LOADLEV x; - int lv,i; - THUMAN *h; + int lv; if (select_mode) @@ -467,13 +466,14 @@ static char load_index_map(int index) return 1; } if (!strcmp(index_tab[last_index].mapname,level_fname)) return 0; + group_all(); lv=find_leave_place(viewsector); if (lv<1) { bott_disp_text(texty[121]); return 0; } - for(i=0,h=postavy;iused && h->lives) if (h->sektor!=lv && !labyrinth_find_path(h->sektor,lv,(SD_PLAY_IMPS | SD_SECRET),flp_validate2,NULL)) { @@ -481,12 +481,11 @@ static char load_index_map(int index) bott_disp_text(int2ascii(i,c,10)); return 0; } + */ if (!GlobEvent(MAGLOB_LEAVEMAP,viewsector,viewdir)) return 0; - for(i=0,h=postavy;iused && h->lives) h->sektor=lv; viewsector=lv; strncpy(x.name,index_tab[index].mapname,12); - x.start_pos=0; + x.start_pos=lv; x.dir=0; macro_load_another_map(&x); return 0; diff --git a/game/inv.c b/game/inv.c index c10c488..9f225af 100644 --- a/game/inv.c +++ b/game/inv.c @@ -1014,7 +1014,7 @@ static void inv_use_spec(short **items) char check_jidlo_voda(THUMAN *p) { if (game_extras & EX_NOHUNGRY) return 0; - if (p->used && p->lives) + if (p->used && p->lives && p->inmaphash == current_map_hash) { p->jidlo--; p->voda--; @@ -1069,7 +1069,7 @@ void pomala_regenerace_postavy(THUMAN *p) char sleep_regenerace(THUMAN *p) { int mreg,mmax; - if (p->used && p->lives) + if (p->used && p->lives && p->inmaphash == current_map_hash) { if (check_jidlo_voda(p)) return 1; p->kondice+=p->vlastnosti[VLS_VPREG]; @@ -2943,7 +2943,7 @@ char shop_change_player(int id, int xa, int ya,int xr,int yr) i=group_sort[i]; p=&postavy[i]; - if (p->used && p->sektor==viewsector) { + if (p->used && p->sektor==viewsector && p->inmaphash == current_map_hash) { if (ms_last_event.event_type & 0x2) { int j=select_player; diff --git a/game/kouzla.c b/game/kouzla.c index f59ce6d..f3c5e13 100644 --- a/game/kouzla.c +++ b/game/kouzla.c @@ -368,7 +368,7 @@ static void spell_vzplanuti3(int ss,int hit,int zivel) { THUMAN *h;int i; - for(i=0,h=postavy;iused && h->lives && h->sektor==ss) + for(i=0,h=postavy;iused && h->lives && h->sektor==ss && h->inmaphash == current_map_hash) { int ochrana=mgochrana(h->vlastnosti[VLS_OHEN+zivel]); player_hit(h,hit*ochrana/100,1); @@ -871,6 +871,7 @@ void spell_pripojeni(int kolik,int cil,int owner) return; } p->sektor=postavy[owner].sektor; + p->inmaphash = postavy[owner].inmaphash; kolik--; for(i=0;igroupnum && postavy[i].sektor==from_sect) @@ -907,6 +908,7 @@ void spell_pripojenia(int owner) { postavy[i].sektor=postavy[owner].sektor; postavy[i].direction=postavy[owner].direction; + postavy[i].inmaphash = postavy[owner].inmaphash; } } auto_group(); @@ -1000,7 +1002,7 @@ void spell_teleport_sector(int cil,int owner) destroy_player_map(); if (stricmp(TelepLocation.map,level_fname)!=0) { - int i; + if (cil!=owner) return; postavy_teleport_effect(0,0,0,1); @@ -1008,14 +1010,8 @@ void spell_teleport_sector(int cil,int owner) loadlevel.name[12]=0; loadlevel.start_pos=TelepLocation.sector; loadlevel.dir=TelepLocation.dir; - send_message(E_CLOSE_MAP); save_map=1; - - for(i=0;iused && h->lives && min>h->lives) min=h->lives; + if (h->used && h->lives && min>h->lives && h->sektor == viewsector && h->inmaphash == current_map_hash) min=h->lives; for(i=0,m=mobs;ivlajky & MOB_LIVE && m->vlajky & MOB_IN_BATTLE && m->liveslives; - for(i=0,h=postavy;iused && h->lives) + for(i=0,h=postavy;iused && h->lives && h->sektor == viewsector && h->inmaphash == current_map_hash) { int obr=mgochrana(h->vlastnosti[VLS_OHEN+zivel]); if (!povaha || (int)rnd(100)<=obr) @@ -1773,7 +1769,7 @@ char add_group_spell(int num,int sector,int owner,int mode,char noanim) else { for(i=0;istart_pos; + send_message(E_CLOSE_MAP); } void macro_drop_item(int sector,int smer,short item) @@ -580,7 +579,7 @@ static void ma_send_experience(int32_t what) for(i=0,maxl=0,h=postavy;iused && maxllevel) maxl=h->level; for(i=0,h=postavy;iused && h->lives) + if (h->used) { h->exp+=what*h->level/maxl; check_player_new_level(h); @@ -626,7 +625,7 @@ static void build_trig_group(char mode,int side) break; case TRIG_SECTOR:side>>=2; for(i=0,h=postavy;iused && h->sektor==side) trig_group|=1<used && h->sektor==side && h->inmaphash == current_map_hash) trig_group|=1< sz) return NULL; + temp_storage_retrieve(name, c, tsz); + c[tsz] = 0; + return c; +} + int load_map(char *filename) { @@ -328,6 +355,9 @@ int load_map(char *filename) exit(0); } doNotLoadMapState=0; + current_map_hash = fnv1a_hash(filename); + const char * hash_str = map_hash_to_string(current_map_hash); + temp_storage_store(hash_str, filename, strlen(filename)); return suc; } @@ -355,6 +385,7 @@ int get_leaving_place(char *level_name) } + void leave_current_map() { int i; @@ -364,7 +395,9 @@ void leave_current_map() kill_all_sounds(); remove_all_mob_spells(); regen_all_mobs(); - if (save_map) save_map_state(); //do tempu se zabali status mapy + if (save_map) { + save_map_state(); //do tempu se zabali status mapy + } destroy_fly_map(); p=letici_veci; while (p!=NULL) {stop_fly(p,0);p=p->next;} @@ -973,8 +1006,10 @@ void mrtva_skupina() { int i=0; - for(i=0;!postavy[i].groupnum || !postavy[i].used;i++); - zmen_skupinu(&postavy[i]); + //najde prvni pouzitelnou postavu + for(i=0;!postavy[i].groupnum || !postavy[i].used || postavy[i].inmaphash != current_map_hash;i++); + //a zmeni + zmen_skupinu(postavy+i); } /* static void check_pod_vodou(char mode) @@ -1016,7 +1051,7 @@ void check_players_place(char mode) { char levitat; for (i = 0; i < POCET_POSTAV; i++, h++) - if (h->used && h->lives) { + if (h->used && h->lives && h->inmaphash == current_map_hash) { int sect; int u1; @@ -1171,7 +1206,7 @@ void zmen_skupinu(THUMAN *p) { int i; - if (p->groupnum==0) {bott_draw(0);return;} + if (p->groupnum==0 || p->inmaphash != current_map_hash) {bott_draw(0);return;} cur_group=p->groupnum; for(i=0;isektor; @@ -1236,11 +1271,11 @@ void group_all(void) { if (cur_group!=1) { - for(i=0,h=postavy;iused && h->groupnum==1 && h->sektor!=viewsector) break; + for(i=0,h=postavy;iused && h->groupnum==1 && h->sektor!=viewsector && h->inmaphash == current_map_hash) break; if (i==POCET_POSTAV) cur_group=1; } for(i=0,h=postavy;iused && h->lives && h->sektor==viewsector) h->groupnum=cur_group; + if (h->used && h->lives && h->sektor==viewsector && h->inmaphash == current_map_hash) h->groupnum=cur_group; } bott_draw(0); @@ -1256,7 +1291,7 @@ void build_player_map() //je nutne volat po presunu postav { int i; THUMAN *p; - for(i=0;p=&postavy[i],iused && p->inmaphash == current_map_hash) { map_coord[p->sektor].flags|=(p->lives?MC_PLAYER:MC_DEAD_PLR); if (mglob.map_effector==ME_PVODA) @@ -1458,7 +1493,7 @@ void check_postavy_teleport() if (ISTELEPORTSECT(viewsector)) { int i,ss=0,sid=viewsector*4+viewdir; - for(i=0;i> 8)-2]; + if (postavy[c].sektor==viewsector && postavy[c].used && postavy[c].inmaphash == current_map_hash) add_to_group(c); zmen_skupinu(postavy+c); bott_draw(1); @@ -1902,7 +1937,7 @@ int postavy_propadnout(int sector) mute_hit_sound=0; if (map_coord[sector].flags & MC_DPLAYER && map_sectors[sector].sector_type==S_DIRA) { - for(i=0;iused && (h->lives || death) && h->sektor==sector) return h; + if (h->used && (h->lives || death) && h->sektor==sector && h->inmaphash == current_map_hash) return h; h++; } } @@ -230,7 +230,7 @@ int numplayers(int sector,char death) int i,c; THUMAN *h; - for(i=0,c=0,h=postavy;iused && (death || h->lives) && h->sektor==sector) c++; + for(i=0,c=0,h=postavy;iused && (death || h->lives) && h->sektor==sector && h->inmaphash == current_map_hash) c++; return c; } @@ -255,7 +255,7 @@ void presun_krok(EVENT_MSG *msg,void **user) { int i; destroy_player_map(); - for (i=0;isector].flags |= MC_AUTOMAP; - for(i=0;igroupnum=t++; for(j=i+1;q=&postavy[j],jsektor==q->sektor && p->direction==q->direction && q->used && q->lives) + if (p->sektor==q->sektor && p->direction==q->direction && p->inmaphash == current_map_hash && q->used && q->lives) q->groupnum=p->groupnum; } } @@ -536,7 +536,7 @@ void zacatek_kola() if (p->used) { postavy[i].programovano=0; - if (p->kondice && p->lives) + if (p->kondice && p->lives && p->inmaphash == current_map_hash) { p->actions=get_ap(p->vlastnosti); // if (p->actions) autostart_round=0; @@ -568,7 +568,7 @@ char check_end_game() for(i=0;iused && p->lives) + if (p->used && p->lives && p->inmaphash == current_map_hash) { end=2; if (p->groupnum==cur_group) return 0; @@ -673,6 +673,22 @@ void wire_end_game() battle=0;running_battle=0; unwire_proc(); for(i=0;i2) + for (i=0;i2 && postavy[i].inmaphash == current_map_hash) { int wf=weigth_defect(postavy+i)+2; if (postavy[i].provadena_akce==NULL || postavy[i].provadena_akce->action!=AC_RUN) return 0; @@ -805,7 +821,7 @@ void utek_postavy(THUMAN *p) int i; p->actions=minact; hromadny_utek=p->sektor; - for (i=0;isektor) + for (i=0;isektor && postavy[i].inmaphash == current_map_hash) { int wf=weigth_defect(postavy+i)+2; postavy[i].kondice-=minact*wf; @@ -1280,9 +1296,9 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje wire_main_functs(); bott_draw(1); running_battle=0; - for(i=0;p=&postavy[i],isektor!=viewsector || !p->used || !p->groupnum);i++); + for(i=0;p=&postavy[i],isektor!=viewsector || !p->used || p->inmaphash != current_map_hash || !p->groupnum);i++); if (i==POCET_POSTAV) - for(i=0;p=&postavy[i],iused || !p->groupnum);i++); + for(i=0;p=&postavy[i],iused || !p->groupnum || p->inmaphash != current_map_hash );i++); cur_group=postavy[i].groupnum; viewsector=postavy[i].sektor; viewdir=postavy[i].direction; @@ -1411,7 +1427,7 @@ char cancel_power(int id,int xa,int ya,int xr,int yr) return 1; } -char ask_who_proc(int id,int xa,int ya,int xr,int yr) +static char ask_who_proc(int id,int xa,int ya,int xr,int yr) { THUMAN *p; int i; @@ -1421,12 +1437,9 @@ char ask_who_proc(int id,int xa,int ya,int xr,int yr) i=xr/xs[0];yr;xa;ya;id; if (isektor!=viewsector; - if (p->used) - if (((!far_play && !c) || (!death_play && c)) && death_play==(p->lives==0)) + if (can_select_player(p, death_play, far_play)) { { if (get_spell_teleport(magic_data->data1)) if ((magic_data->data2=select_teleport_target())==0) @@ -1443,6 +1456,7 @@ char ask_who_proc(int id,int xa,int ya,int xr,int yr) return 1; } } + } return 0; } @@ -1777,6 +1791,7 @@ static void zahajit_kolo(char prekvapeni) for(i=0;iinmaphash != current_map_hash) continue; int sect=p->sektor,dir=p->direction; char monster=0; char monster_far=0; @@ -1809,7 +1824,7 @@ static void zahajit_kolo(char prekvapeni) if (w==0) w=select_weapon(p,0); else if (w==3) w=select_weapon(p,0),monster|=monster_far; else w--,monster|=monster_far; - if (p->used && !p->programovano && p->lives) { + if (p->used && !p->programovano && p->lives && p->inmaphash == current_map_hash) { if (prekvapeni || !p->actions || !autoattack || !monster) { p->programovano++;p->zvolene_akce->action=AC_STAND; @@ -2059,7 +2074,7 @@ int pocet_zivych(int sector) { THUMAN *p=&postavy[i]; - if (p->used && p->lives && p->sektor==sector) z++; + if (p->used && p->lives && p->sektor==sector && p->inmaphash == current_map_hash) z++; } return z; } @@ -2144,7 +2159,7 @@ char zasah_veci(int sector,TFLY *fl) for(i=0;isektor && p->lives && p->used) + if (sector==p->sektor && p->lives && p->used && p->inmaphash == current_map_hash) { char death; short vlastnosti[VLS_MAX]; @@ -2250,7 +2265,7 @@ void wire_cast_spell() void wire_fly_casting(int i) { - if (!postavy[i].used || !postavy[i].lives) return; + if (!postavy[i].used || !postavy[i].lives || postavy[i].inmaphash != current_map_hash) return; magic_data=&spell_string; memset(&spell_string,0,sizeof(spell_string)); after_spell_wire=wire_cast_spell; diff --git a/game/specproc.c b/game/specproc.c index b99e131..da061c7 100644 --- a/game/specproc.c +++ b/game/specproc.c @@ -59,11 +59,11 @@ MAP_PROC(map_teleport) int i,j=-1;THUMAN *h; int bit=0; - for(i=0,h=postavy;iused && h->sektor==sector && h->sektor==viewsector) + for(i=0,h=postavy;iused && h->sektor==sector && h->sektor==viewsector && h->inmaphash == current_map_hash) { j=i;break; } - for(i=0,h=postavy;iused && h->sektor==sector) bit|=1<used && h->sektor==sector && h->inmaphash == current_map_hash) bit|=1<direction,bit,j!=-1); side=1; auto_group(); @@ -538,7 +538,7 @@ static char mob_strelec(int event_type,TMOB *m) int i; for(i=0,h=postavy;ilives && h->used && + if (h->lives && h->used && h->inmaphash == current_map_hash&& abs(map_coord[h->sektor].x-map_coord[m->sector].x)<2 && abs(map_coord[h->sektor].y-map_coord[m->sector].y)<2) { diff --git a/libs/bgraph.h b/libs/bgraph.h index aded251..fa45453 100644 --- a/libs/bgraph.h +++ b/libs/bgraph.h @@ -96,6 +96,7 @@ void showview32(word x,word y,word xs,word ys); void showview256(word x,word y,word xs,word ys); void showview_lo(word x,word y,word xs,word ys); void outtext(const char *text); +void outtext_w_nl(const char *text); int initmode(const INI_CONFIG_SECTION *, const char *app_name); int initmode32(void); int initmode32b(void); diff --git a/libs/bgraph2.c b/libs/bgraph2.c index 1e92d56..a6e57a6 100644 --- a/libs/bgraph2.c +++ b/libs/bgraph2.c @@ -72,6 +72,41 @@ void outtext(const char *text) } } +void outtext_w_nl(const char *text) + { + byte pos; + int savewriteposx = writeposx; + + if (fontdsize) + while (*text) + { + if (*text == '\n') { + writepos -= writeposx - savewriteposx - GetScreenPitch() * (charsize(curfont, 'X') >> 8); + writeposx = savewriteposx; + } else { + char2_32(writepos,curfont,*text); + pos=(charsize(curfont,*text) & 0xff)<<1; + writepos+=pos; + writeposx+=pos; + } + text++; + } + else + while (*text) + { + if (*text == '\n') { + writepos -= writeposx - savewriteposx - GetScreenPitch() * (charsize(curfont, 'X') >> 8); + writeposx = savewriteposx; + } else { + char_32(writepos,curfont,*text); + pos=charsize(curfont,*text) & 0xff; + writepos+=pos; + writeposx+=pos; + } + text++; + } + } + /*MODEinfo vesadata[3]; SVGAinfo svgadata[3]; int lastbank=0; diff --git a/platform/platform.h b/platform/platform.h index e0982d7..8f993c8 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -20,6 +20,7 @@ extern "C" #define _KEYBRD_READ 1 #define TIMERSPEED 20 +extern int timerspeed_val; uint32_t _bios_keybrd(int mode); @@ -27,6 +28,8 @@ uint32_t _bios_keybrd(int mode); #define RGB888(r,g,b) ((unsigned short)((((r)<<7)&0x7C00) | (((g)<<2) & 0x3E0) | ((b)>>3))) #define RGB555(r,g,b) (((unsigned short)(((r)<<10) | ((g)<<5) | (b))) & ~BGSWITCHBIT) #define RGB555_ALPHA(r,g,b) (((unsigned short)(((r)<<10) | ((g)<<5) | (b))) | BGSWITCHBIT) +#define AVG_PIXEL_MASK (0x7BDE) +#define BLEND_PIXELS(px1, px2) ((((px1) & AVG_PIXEL_MASK) + ((px2) & AVG_PIXEL_MASK)) >> 1) diff --git a/platform/timer.cpp b/platform/timer.cpp index 3a68a03..a3c1d88 100644 --- a/platform/timer.cpp +++ b/platform/timer.cpp @@ -3,9 +3,12 @@ #include "platform.h" #include + +int timerspeed_val = TIMERSPEED; + int get_timer_value() { auto n = std::chrono::steady_clock::now(); - return std::chrono::duration_cast(n.time_since_epoch()).count()/TIMERSPEED; + return std::chrono::duration_cast(n.time_since_epoch()).count()/timerspeed_val; } uint32_t get_game_tick_count() {