#include #include #include #include #include #include #include #include #include #include #include #include #include #include "engine1.h" #include #include "globals.h" #include #include "lang.h" #include #include #define A_OPEN_DOOR 1 #define A_CLOSE_DOOR 2 #define A_OPEN_CLOSE 3 #define A_RUN_PRIM 4 #define A_SHOW_PRIM 5 #define A_HIDE_PRIM 6 #define A_SHOW_HIDE_PRIM 7 #define A_RUN_SEC 8 #define A_SHOW_SEC 9 #define A_HIDE_SEC 10 #define A_SHOW_HIDE_SEC 11 #define A_HIDE_PRIM_SEC 12 #define A_DISPLAY_TEXT 13 #define A_CODELOCK_LOG 14 #define A_OPEN_TELEPORT 15 #define A_CLOSE_TELEPORT 16 #define A_CODELOCK_LOG2 17 #define MAX_FLY_SECT 4 #define DIS (char *)0x1 #define START_HANDLE hl_ptr extern TSTR_LIST texty_v_mape; char pass_zavora=0; char map_with_password=0; MAPGLOBAL mglob={ {"","","",""},0,0,0,1,0,"",0,0,0 }; TSTENA *map_sides; TSECTOR *map_sectors; TVYKLENEK *map_vyk; //mapa vyklenku word vyk_max; //pocet vyklenku v mape short **map_items; char *flag_map; TMAP_EDIT_INFO *map_coord; TSTR_LIST level_texts; int mapsize; int num_ofsets[10]; //tabulka ofsetu pro cisla sten k levelu 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; char break_sleep=0; char enable_sort=0; int sleep_ticks=MAX_SLEEP; char side_touched=1; char save_map=1; //char formace=0; char last_send_action; //naposled vyslana akce char insleep=0; short moving_player=0; char force_start_dialog=0; int start_dialog_number=0; int start_dialog_mob=0; uint32_t current_map_hash; int32_t money=0; char runes[5]={0,0,0,0,0}; char group_sort[POCET_POSTAV]={0,1,2,3,4,5}; int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size) // { int32_t s; char c[20]; *section=NULL; fread(c,1,sizeof(sekceid),f); if (strcmp(c,sekceid)) return -1; fread(sct_type,1,sizeof(*sct_type),f); fread(sect_size,1,sizeof(*sect_size),f); fread(&s,1,sizeof(s),f); *section=getmem(*sect_size); s=fread(*section,1,*sect_size,f); return s; } void prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class) { char *p,*end; end=names+size; p=names; while (p sz) return NULL; temp_storage_retrieve(name, c, tsz); c[tsz] = 0; return c; } int load_map(char *filename) { FILE *f; void *temp; int sect; int32_t size,r; char nmapend=1; int ofsts=START_HANDLE; char snd_load=0; void *mob_template; int32_t mob_size; int failed = 0; map_with_password=0; const char *mpath = build_pathname(2, gpathtable[SR_MAP], filename); mpath = local_strdup(mpath); schovej_mysku(); zobraz_mysku(); f=fopen_icase(mpath,"rb"); if (level_fname!=NULL) free(level_fname); level_fname=(char *)getmem(strlen(filename)+1); strcpy(level_fname,filename); SEND_LOG("(GAME) Loading map: '%s'",level_fname); strupper(level_fname); mob_template=NULL; mob_size=0; if (f==NULL) return -1; do { r=load_section(f,&temp,§,&size); if (r==size) switch (sect) { case A_SIDEMAP: map_sides=temp; break; case A_SECTMAP: map_sectors=temp; break; case A_MAPINFO: map_coord=temp; mapsize=size / sizeof(TMAP_EDIT_INFO); init_items(); init_mobs(); break; case A_MAPEND: nmapend=0; free(temp); break; case A_STRMAIN: num_ofsets[0]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); free(temp); break; case A_STRLEFT: num_ofsets[1]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); free(temp); break; case A_STRRIGHT: num_ofsets[2]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); free(temp); break; case A_STRCEIL: num_ofsets[3]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA); free(temp); break; case A_STRFLOOR: num_ofsets[4]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA); free(temp); break; case A_STRARC: num_ofsets[OBL_NUM]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); free(temp); break; case A_STRARC2: num_ofsets[OBL2_NUM]=ofsts-1; prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); free(temp); break; case A_MAPGLOB: num_ofsets[BACK_NUM]=ofsts; memset(&mglob,0,sizeof(mglob)); memcpy(&mglob,temp,MIN((int)size,(int)sizeof(mglob))); free(temp); for(r=0;r<4;r++) def_handle(ofsts++,mglob.back_fnames[r],pcx_fade_decomp,SR_GRAFIKA); back_color=RGB888(mglob.fade_r,mglob.fade_g,mglob.fade_b); break; case A_MAPITEM: SEND_LOG("(GAME) Loading items..."); load_item_map(temp,size); free(temp); break; case A_MAPMOBS: if (snd_load==0) create_sound_table_old(); SEND_LOG("(GAME) Loading enemies..."); if (mob_template==NULL) { int32_t h;const char *p; alock(H_ENEMY); p=ablock(H_ENEMY); h=get_handle_size(H_ENEMY); load_enemies(temp,size,&ofsts,(TMOB *)p,h); aunlock(H_ENEMY); } else { load_enemies(temp,size,&ofsts,mob_template,mob_size); free(mob_template); SEND_LOG("(GAME) Loading enemies from map template..."); } free(temp); break; case A_MAPMACR: SEND_LOG("(GAME) Loading multiactions..."); load_macros(size,temp); break; case A_MAPVYK: map_vyk=temp; vyk_max=size/sizeof(TVYKLENEK); break; case A_MOBS: mob_template=temp; mob_size=size; break; case A_MOBSND: snd_load=1; create_sound_table(temp,size); free(temp); break; case A_PASSW : map_with_password=1; free(temp); break; default:free(temp); } else { if (temp!=NULL)free(temp); fclose(f); return -3; } } while (nmapend); fclose(f); flag_map=(char *)getmem(mapsize*4); memset(minimap,0,sizeof(minimap)); end_ptr=ofsts; const char *tpath=set_file_extension(mpath,".txt"); failed=load_level_texts(tpath); if (!failed && level_texts!=NULL) { lang_patch_stringtable(&level_texts, filename, "map_"); create_playlist(level_texts[0]); } init_tracks(); change_music(get_next_music_from_playlist()); for(r=0;rnext;} calc_fly(0); save_map=1; free(map_sides); free(map_sectors); free(flag_map); free(map_coord); free(map_vyk);map_vyk=NULL;vyk_max=0; if (texty_v_mape!=NULL)release_list(texty_v_mape); while (d_action!=NULL) { void *p=d_action; d_action=d_action->next; free(p); } texty_v_mape=NULL; release_list(level_texts); if (mob_map!=NULL) free(mob_map); if (macro_block!=NULL) { free(macro_block); macros=NULL; macro_block=NULL; macro_block_size=0; } if (map_items!=NULL) { for(i=0;iloadproc==pcx_fade_decomp) zneplatnit_block(i); } for(i=hl_ptr;i>=24; flags&=0x1f; return q->flags ^ flags; } void recheck_button(int sector,char auto_action) { TSECTOR *ts; short **ms; char swch; char flrpls[]={1,2,2,4,4,8,2,2}; ts=map_sectors+sector; if (ts->sector_type!=S_TLAC_OFF && ts->sector_type!=S_TLAC_ON) return; ms=map_items+(sector<<2); swch=(map_coord[sector].flags & MC_DPLAYER || mob_map[sector] || ms[0]!=NULL || ms[1]!=NULL || ms[2]!=NULL || ms[3]!=NULL); switch (ts->sector_type) { case S_TLAC_OFF:if (swch) { ts->floor+=flrpls[ts->flags & 7]; ts->sector_type=S_TLAC_ON; if (auto_action) do_action(ts->action,ts->sector_tag,ts->side_tag,0,0); } break; case S_TLAC_ON:if (!swch) { ts->floor-=flrpls[ts->flags & 7]; ts->sector_type=S_TLAC_OFF; if (auto_action) do_action(ts->action,ts->sector_tag,ts->side_tag,0,0); } break; } } void stop_fly(LETICI_VEC *p,char zvuk) { if (zvuk && ~p->flags & FLY_NEDULEZITA)sirit_zvuk(p->sector); if (!(p->flags & FLY_DESTROY)) { item_sound_event(p->items==NULL?p->item:p->items[0],p->sector); if (p->xpos>=0) push_item(p->sector,(p->smer+(p->ypos>0))&3,p->items); else push_item(p->sector,(p->smer+(p->ypos<0)+2)&3,p->items); } p->flags |= FLY_BURNT; } void interrupt_fly(LETICI_VEC *p) { if (p->flags & FLY_DESTROY_SEQ) return; p->speed=0; if (p->flags & FLY_DESTROY) { p->flags|=FLY_DESTROY_SEQ|FLY_NEHMOTNA; p->anim_pos=3; p->velocity=0; item_sound_event(p->items==NULL?p->item:p->items[0],p->sector); } else if (p->velocity==0) stop_fly(p,1);else if (p->velocity<10) p->velocity=10; } LETICI_VEC *create_fly() { LETICI_VEC *p,*q; p=letici_veci; q=NULL; while (p!=NULL) if (p->flags & FLY_UNUSED) { if (q==NULL) letici_veci=p->next;else q->next=p->next; free(p->items); break; } else { q=p; p=p->next; } if (p==NULL) p=New(LETICI_VEC); p->flags=0; p->items=NULL; p->item=0; p->lives=0; return p; } TFLY *duplic_fly(TFLY *p) { TFLY *q; q=create_fly(); *q=*p; if (q->items!=NULL) { int s=0; while (q->items[s]) ++s; ++s; q->items=(short *)getmem(s); memcpy(q->items,p->items,s); } return q; } void calc_fly(THE_TIMER *t) { LETICI_VEC *p,*q; short ss; for(p=letici_veci;p!=NULL;p=q) { p->xpos+=p->speed; if (p->flags & FLY_BURNT) { if (p->flags & FLY_UNUSED) { short ds[2]; if (letici_veci==p) letici_veci=p->next; else { for(q=letici_veci;q->next!=p;q=q->next); q->next=p->next; } q=p->next; ds[0]=p->item;ds[1]=0; if (p->items!=NULL) destroy_items(p->items); else destroy_items(ds); free(p->items); p->items=NULL; free(p); continue; } else { q=p->next; continue; } } q=p->next; if (!(p->flags & FLY_NEHMOTNA)) { p->velocity+=1; } p->zpos-=p->velocity; ss=p->sector; if (!(p->flags & FLY_NEDULEZITA)) neco_v_pohybu=1; if (p->zpos>110) p->zpos=110; if (p->zpos<=20) { if (map_sectors[p->sector].sector_type==S_DIRA) { p->speed=0; if (p->zpos<=-128) { p->sector=map_sectors[p->sector].sector_tag; p->zpos=256; } } else stop_fly(p,1); continue; } if (p->flags & FLY_IN_FLY && p->xpos>-16 && zasah_veci(p->sector,p)) { interrupt_fly(p); continue; } if (p->xpos>63) { p->flags|=FLY_IN_FLY; p->xpos-=127; ss=map_sectors[p->sector].step_next[p->smer]; if (p->sector != 0 && !(map_sides[p->sector*4+p->smer].flags & SD_THING_IMPS)) { p->sector=ss; if (ISTELEPORTSECT(p->sector)) p->sector=map_sectors[p->sector].sector_tag; } else { p->xpos+=127-p->speed; if (!zasah_veci(p->sector,p) && p->lives) p->lives--; if (p->lives) { TFLY *q,*z; q=duplic_fly(p);q->smer=(p->smer+1)&3; z=duplic_fly(p);z->smer=(p->smer-1)&3; add_fly(q); add_fly(z); } interrupt_fly(p); } } else if (p->counter++ > 100) { zasah_veci(p->sector,p); interrupt_fly(p); continue; } } } void destroy_all_fly() { while (letici_veci) { TFLY *f = letici_veci; letici_veci = f->next; if (f->items) free(f->items); free(f); } } extern int32_t sound_side_flags; void calc_animations() { int i; for (i=0;iflags; pj=p->prim_anim>>4;pk=p->prim_anim & 15; sj=p->sec_anim>>4;sk=p->sec_anim & 15; if (!pk && !sk) continue; if (p->flags & SD_PRIM_ANIM) { if (p->flags & SD_PRIM_GAB) if (pj==0 || pj==pk) p->flags^=SD_PRIM_FORV; if (p->flags & SD_PRIM_FORV) pj++; else pj--; if (pj>pk) pj=0; if (pj<0) pj=pk; } else { if (p->flags & SD_PRIM_FORV) pj++; else pj--; if (pk && (pj+(!(p->flags & SD_PRIM_FORV))==pk)) {p->flags&=~0xff;p->flags|=flag_map[i];} if (pj>pk) pj=pk; else if (pj<0) pj=0; else call_macro(i,MC_ANIM|((pj & 1)?MC_ANIM2:0)|(pj?0:MC_CLOSEDOOR)|(pj==pk?MC_OPENDOOR:0)); if (pk==pj && p->flags & SD_PRIM_GAB) p->flags&=~SD_PRIM_FORV; } if (p->flags & SD_SEC_ANIM) { if (p->flags & SD_SEC_GAB) if (sj==0 || sj==sk) p->flags^=SD_SEC_FORV; if (p->flags & SD_SEC_FORV) sj++; else sj--; if (sj>sk) sj=0; if (sj<0) sj=sk; } else { if (p->flags & SD_SEC_FORV) sj++; else sj--; if (!pk && sk && (sj+(!(p->flags & SD_SEC_FORV))==sk)) {p->flags&=~0xff;p->flags|=flag_map[i];} if (sj>sk) sj=sk; else if (sj<0) sj=0; else if (!pk) call_macro(i,MC_ANIM|((sj & 1)?MC_ANIM2:0)|(pj?0:MC_CLOSEDOOR)); if (sk==sj && p->flags & SD_SEC_GAB) p->flags&=~SD_SEC_FORV; } p->prim_anim=(pj<<4)+pk; p->sec_anim=(sj<<4)+sk; } sound_side_flags=0; } void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay) { D_ACTION *d; if (!sector && !direct) return; if (!delay) do_action(action_numb,sector,direct,flags,nosend); else { d=(D_ACTION *)getmem(sizeof(D_ACTION)); d->action=action_numb; d->sector=sector; d->side=direct; d->flags=flags>>16; d->nocopy=nosend; d->delay=delay; d->next=d_action; d_action=d; } } /* int get_action_delay(TSTENA *q) { if (q->flags & SD_DELAY) { if (q->sec) return q->sec_anim & 0xf; return q->prim_anim & 0xf; } else return 0; } */ void check_codelock_log(int sector,uint32_t flags) { int i; TSTENA *p; TSECTOR *s; p=&map_sides[sector*4]; s=&map_sectors[sector]; for (i=0;i<4;i++) if (!(p[i].flags & SD_PRIM_VIS)) break; if (i==4) do_action(s->action,s->sector_tag,s->side_tag,flags,0); } int do_action(int action_numb,int sector, int direct,int flags, int nosend) { TSTENA *q; TSECTOR *s; char *c; int sid; char ok=0; sid=sector*4+direct; s=&map_sectors[sector]; q=&map_sides[sid]; c=&flag_map[sid]; switch (action_numb) { case 0: q->flags=actn_flags(q,flags); break; case A_OPEN_DOOR: if (!(q->flags & SD_PRIM_FORV) && !(q->flags & SD_PRIM_ANIM)) { q->flags|=SD_PRIM_FORV; *c=(char)actn_flags(q,flags); ok=1; } if (!(q->flags & SD_SEC_FORV)) { q->flags|=SD_SEC_FORV; ok=1; } sound_side_flags=q->flags; break; case A_CLOSE_DOOR: if (q->flags & SD_PRIM_FORV && !(q->flags & SD_PRIM_ANIM)) { q->flags&=~SD_PRIM_FORV; *c=(char)actn_flags(q,flags); ok=1; } if (q->flags & SD_SEC_FORV) { q->flags&=~SD_SEC_FORV; ok=1; } sound_side_flags=q->flags; break; case A_OPEN_CLOSE: if (!(q->flags & SD_PRIM_ANIM)) q->flags^=SD_PRIM_FORV | SD_SEC_FORV; else q->flags^= SD_SEC_FORV ; *c=(char)actn_flags(q,flags); ok=1; sound_side_flags=q->flags; break; case A_RUN_PRIM: q->flags|=SD_PRIM_ANIM; ok=1; break; case A_HIDE_PRIM: if (q->flags & SD_PRIM_VIS) { q->flags&=~SD_PRIM_VIS; *c=(q->flags=actn_flags(q,flags)); ok=1; } break; case A_SHOW_PRIM: if (!(q->flags & SD_PRIM_VIS)) { q->flags|=SD_PRIM_VIS; *c=(q->flags=actn_flags(q,flags)); ok=1; } break; case A_SHOW_HIDE_PRIM: q->flags^=SD_PRIM_VIS; *c=(q->flags=actn_flags(q,flags)); ok=1; break; case A_RUN_SEC: q->flags|=SD_SEC_ANIM; ok=1; break; case A_HIDE_SEC: if (q->flags & SD_SEC_VIS) { q->flags&=~SD_SEC_VIS; *c=(q->flags=actn_flags(q,flags)); ok=1; } break; case A_SHOW_SEC: if (!(q->flags & SD_SEC_VIS)) { q->flags|=SD_SEC_VIS; *c=(q->flags=actn_flags(q,flags)); ok=1; } break; case A_SHOW_HIDE_SEC: q->flags^=SD_SEC_VIS; *c=(q->flags=actn_flags(q,flags)); ok=1; break; case A_HIDE_PRIM_SEC: if ((q->flags & SD_SEC_VIS)||(q->flags & SD_PRIM_VIS)) { q->flags&=~(SD_SEC_VIS+SD_PRIM_VIS); *c=(q->flags=actn_flags(q,flags)); ok=1; } break; case A_DISPLAY_TEXT: bott_disp_text(level_texts[sector]); ok=1; return 0; case A_CODELOCK_LOG2: check_codelock_log(sector,flags); q->flags^=SD_PRIM_VIS; check_codelock_log(sector,flags); ok=1; break; case A_CODELOCK_LOG: check_codelock_log(sector,0x1f000000); q->flags^=SD_PRIM_VIS; check_codelock_log(sector,0x1f000000); ok=1; break; case A_OPEN_TELEPORT: ok=(s->sector_type!=S_TELEPORT); s->sector_type=S_TELEPORT; { int i; for(i=0;i<4;i++) map_sides[(sector<<2)+i].flags|=SD_SEC_VIS; } nosend=1; break; case A_CLOSE_TELEPORT: ok=(s->sector_type==S_TELEPORT); s->sector_type=S_NORMAL; { int i; for(i=0;i<4;i++) map_sides[(sector<<2)+i].flags&=~SD_SEC_VIS; } nosend=1; break; } if (nosend) return 0; last_send_action=action_numb; call_macro(sid,MC_INCOMING); if (ok) { ok=0; call_macro(sid,MC_SUCC_DONE); } if (q->flags & SD_COPY_ACTION) { q->flags&=~SD_COPY_ACTION; delay_action(action_numb,q->sector_tag,q->side_tag,flags,0,0); q->flags|=SD_COPY_ACTION; } if (q->flags & SD_SEND_ACTION) { q->flags&=~SD_SEND_ACTION; delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); q->flags|=SD_SEND_ACTION; } if (q->flags & SD_APPLY_2ND && s->step_next[direct]) do_action(action_numb,s->step_next[direct],(direct+2)&3,flags,1); return 0; } /* void black(int i,int sector,int dir) { int xl,y1,xr,y2; if (!(map_sides[sector*4+dir].flags & SD_INTERIER)) return; y2=MIDDLE_Y+points[i][0][VIEW3D_Z].y+16; y1=MIDDLE_Y+points[i][1][VIEW3D_Z].y+16; if (i<0) { xl=MIDDLE_X-points[i][0][VIEW3D_Z].x; xr=MIDDLE_X-points[i+1][0][VIEW3D_Z].x; } else if (i>0) { xl=MIDDLE_X+points[i-1][0][VIEW3D_Z].x; xr=MIDDLE_X+points[i][0][VIEW3D_Z].x; } else { xl=MIDDLE_X-points[0][0][VIEW3D_Z].x; xr=MIDDLE_X+points[0][0][VIEW3D_Z].x; } if (xl<0) xl=0; if (xr>639) xr=639; curcolor=back_color; bar(xl,y1,xr,y2); } */ void do_delay_actions() { D_ACTION *d,*p,*q; d=d_action;p=NULL; while (d!=NULL) { if (!(--d->delay)) { q=d; if (q==d_action) { d_action=d->next; d=d_action; } else { p=d_action; while (p->next!=d) p=p->next; p->next=d->next; d=p->next; } do_action(q->action,q->sector,q->side,q->flags<<16,q->nocopy); free(q); } else { d=d->next; } } } void mrtva_skupina() { int i=0; //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) { short sectors[POCET_POSTAV]; short psec; short pp=0; int i,j; for(i=0;ikondice) h->kondice-=ziv*2; else { player_hit(h,h->lives,0); } if (h->kondice<0) h->kondice=0; bott_draw(0); } void check_players_place(char mode) { int i; THUMAN *h = postavy; char vir_eff = 0; static char vir_zavora = 0; char levitat; for (i = 0; i < POCET_POSTAV; i++, h++) if (h->used && h->lives && h->inmaphash == current_map_hash) { int sect; int u1; levitat = (h->vlastnosti[VLS_KOUZLA] & SPL_LEVITATION) != 0; sect = h->sektor; if (sect >= mapsize) continue; switch (map_sectors[sect].sector_type) { case S_ACID: if (!levitat) { if (h->lives > 3) { h->lives -= 3; bott_draw(0); } else { player_hit(h, 3 + 7 * mode, 0); } } break; case S_VIR: if (!levitat) { if (mode == 0 && vir_zavora == 0) { int i, smer; vir_zavora = 1; pass_zavora = 0; smer = rnd(100) < 50 ? -1 : 1; if (vir_eff == 0) for (i = 0; i < 8; i++) turn_zoom(smer); vir_eff = 1; vir_zavora = 0; cancel_pass = 1; } } break; case S_LAVA: if (!levitat) { u1 = (h->lives); player_hit(h, u1, 0); bott_draw(0); } else { if (h->lives > 3) { h->lives -= 3; bott_draw(0); } else player_hit(h, 3 + 7 * mode, 0); } break; case S_SSMRT: u1 = (h->lives); player_hit(h, u1, 0); bott_draw(0); break; case S_VODA: if (!levitat) { akce_voda(h, mode); } break; case S_DIRA: if (!pass_zavora) postavy_propadnout(sect); break; case S_LODKA: if (lodka != 1 && mode) { set_backgrnd_mode(1); lodka = 1; } break; } if (mglob.map_effector == ME_PVODA && ~map_coord[h->sektor].flags & MC_SAFEPLACE) akce_voda(h, mode); if (map_sectors[sect].sector_type != S_LODKA && lodka) { set_backgrnd_mode(0); lodka = 0; } } } static void move_lodka(int oldsect,int newsect) { if (map_sectors[oldsect].sector_type==S_LODKA && map_sectors[newsect].sector_type==S_VODA) { map_sectors[oldsect].sector_type=S_VODA; map_sectors[newsect].sector_type=S_LODKA; } } void calc_game() { int d; calc_animations(); if (d_action!=NULL) do_delay_actions(); calc_mobs(); if (force_start_dialog && !norefresh && !cancel_render) { force_start_dialog=0; call_dialog(start_dialog_number,start_dialog_mob); } check_players_place(0); if ((d=check_end_game())!=0) { if (d==1) wire_end_game();else mrtva_skupina(); } if (battle && cur_mode!=MD_INBATTLE) { start_battle(); } else if(!battle && select_player!=-1) { select_player=-1; bott_draw(0); } } void a_touch(int sector,int dir) { TSTENA *q; int sid; sid=sector*4+dir; q=&map_sides[sid]; if (q->flags & SD_PASS_ACTION) return; if (q->sec && ~q->flags & SD_SEC_VIS) return; side_touched=1; if (!q->sec) delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); else if (q->flags & SD_SEC_VIS) { if (q->flags & SD_AUTOANIM) do_action(A_OPEN_CLOSE,sector,dir,0,1); delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); } call_macro(sid,MC_TOUCHSUC); } void a_pass(int sector, int dir) { TSTENA *q; q=&map_sides[sector*4+dir]; q->flags&=~SD_SECRET; if (q->flags & SD_ALARM) { if (GlobEvent(MAGLOB_ALARM,viewsector,viewdir)) sirit_zvuk(map_sectors[sector].step_next[dir]); } if (!(q->flags & SD_PASS_ACTION)) return; delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); } void zmen_skupinu(THUMAN *p) { int i; if (p->groupnum==0 || p->inmaphash != current_map_hash) {bott_draw(0);return;} cur_group=p->groupnum; for(i=0;isektor; viewdir=p->direction; schovej_mysku(); bott_draw(0); other_draw(); ukaz_mysku(); showview(0,378,640,480); ukaz_mysku(); cancel_render=1; } void sort_groups() { int i,j,t=0; if (cur_mode==MD_PRESUN) group_sort[0]=moving_player; if (enable_sort) { for(i=0;iused && h->groupnum==1 && h->sektor!=viewsector) break; if (i==POCET_POSTAV) cur_group=1; } for(i=0,h=postavy;iused && h->lives && h->sektor==viewsector) h->groupnum=cur_group; } bott_draw(0); } void destroy_player_map() //je nutne volat pred presunem postav { int i; for(i=0;iused && p->inmaphash == current_map_hash) { map_coord[p->sektor].flags|=(p->lives?MC_PLAYER:MC_DEAD_PLR); if (mglob.map_effector==ME_PVODA) { if (q_item_one(i,water_breath+1))map_coord[p->sektor].flags|=MC_SAFEPLACE; } } } char chod_s_postavama(char sekupit) { int i; char gatt=0; signed char group_nums[7]; destroy_player_map(); if (cur_mode==MD_PRESUN) { postavy[select_player].sektor=viewsector; postavy[select_player].direction=viewdir; } else { memset(group_nums,0xff,sizeof(group_nums)); group_nums[0]=0; for(i=0;imsg==E_INIT || msg->msg==E_DONE) return; check_all_mobs(); calc_game();msg;data; SEND_LOG("(GAME) STEP"); } void do_halucinace() { hal_sector=rnd(mapsize-1)+1; hal_dir=rnd(4); } void sector0(void) { int i; for(i=0;iused && h->groupnum==grp && h->lives && (h->vlastnosti[VLS_POHYB]==0 || h->kondice==0)) return 0; return 1; } void step_zoom(char smer) { char nopass; uint8_t drs; int sid,nsect,sect; char can_go=1; if (running_anm) return; if (pass_zavora) return; if (lodka && (smer==1 || smer==3)) return; cancel_pass=0; drs=(viewdir+smer)&3; sid=viewsector*4+drs; sect=viewsector; call_macro(sid,MC_EXIT); nopass=(map_sides[sid].flags & SD_PLAY_IMPS); if (nopass) call_macro(sid,MC_PASSFAIL);else call_macro(sid,MC_PASSSUC); if (cur_mode==MD_PRESUN) { select_player=moving_player; if(!postavy[select_player].actions) nopass=1; } else can_go=test_can_walk(cur_group); if (!can_go) { bott_disp_text(texty[220]); return; } if (force_start_dialog) cancel_pass=1; if (cancel_pass) return; if (!GlobEvent(MAGLOB_ONSTEP,viewsector,viewdir)) return; if (viewsector!=sect) nsect=viewsector,viewsector=sect;else nsect=map_sectors[viewsector].step_next[drs]; if (map_sectors[nsect].sector_type==S_SCHODY) { int i; viewdir=(viewdir+map_sectors[nsect].side_tag) & 3; nsect=map_sectors[nsect].sector_tag; i=mob_map[nsect]; while (i!=0) { i--; mobs[i].sector=mobs[i].home_pos; i=mobs[i].next; } mob_map[nsect]=0; } else if (mob_map[nsect] && !nopass) { if (!battle){ if (!pass_all_mobs && !mob_alter(nsect)) return; } else return; } if (map_sectors[nsect].sector_type==S_LODKA) { int i; THUMAN *h; group_all();can_go=1; for(i=0,h=postavy;iused && h->inmaphash == current_map_hash && h->groupnum!=cur_group && h->lives) break; if (i!=POCET_POSTAV) { bott_disp_text(texty[66]); return; } } pass_zavora=1; norefresh=1; schovej_mysku(); anim_sipky(H_SIPKY_S+smer,1); anim_sipky(0,255); hide_ms_at(385); ukaz_mysku(); redraw_ms_cursor_on_screen(); if (set_halucination) do_halucinace(); if (loadlevel.name[0]) { if (!battle) { pass_zavora=0; return; } nopass=1; loadlevel.name[0]=0; exit_wait=0; } if (!can_go) nopass=1; if (!nopass) { a_pass(viewsector,drs); viewsector=nsect; move_lodka(sect,nsect); chod_s_postavama(1); send_message(E_KROK); } if (!cancel_pass) { render_scene(viewsector,viewdir); OutBuffer2nd(); sort_groups(); bott_draw(0); other_draw(); if (!nopass) shift_zoom(smer); if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); sort_groups(); bott_draw(0); other_draw(); } update_mysky(); ukaz_mysku(); if (!cancel_render) showview(0,0,0,0); norefresh=0; cancel_render=1; mix_back_sound(0); viewsector=postavy_propadnout(viewsector); check_postavy_teleport(); recheck_button(sect,1); recheck_button(viewsector,1); check_players_place(1); cancel_pass=0; pass_zavora=0; if (force_start_dialog) { force_start_dialog=0; call_dialog(start_dialog_number,start_dialog_mob); } if (cur_mode==MD_GAME) recalc_volumes(viewsector,viewdir); } void turn_zoom(int smer) { if (running_anm) return; if (pass_zavora) return; else pass_zavora = 1; if (!GlobEvent(MAGLOB_ONTURN, viewsector, viewdir)) return; if (set_halucination) do_halucinace(); norefresh = 1; hold_timer(TM_BACK_MUSIC, 1); viewdir = (viewdir + smer) & 3; recalc_volumes(viewsector, viewdir); render_scene(viewsector, viewdir); hide_ms_at(387); OutBuffer2nd(); other_draw(); bott_draw(0); if (smer == 1) { anim_sipky(H_SIPKY_SV, 1); anim_sipky(0, 255); turn_left(); } else { anim_sipky(H_SIPKY_SZ, 1); anim_sipky(0, 255); turn_right(); } chod_s_postavama(0); if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); update_mysky(); ukaz_mysku(); showview(0, 0, 0, 0); if (!battle) calc_game(); norefresh = 0; cancel_render = 1; hold_timer(TM_BACK_MUSIC, 0); mix_back_sound(0); pass_zavora = 0; } int check_path(word **path,word tosect) { word *p,*n,ss; char ok; int i=0; p=*path; n=p+1;ok=0; while (*p!=tosect) { if (map_sectors[*n].sector_type!=S_DIRA && ISTELEPORTSECT(*n)) { for(i=0;i<4 && map_sectors[*p].step_next[i]!=*n;i++) { if (i==4) { ss=*p; free(*path);*path=NULL; return ss; } } if (!(map_sides[(*p<<2)+i].flags & SD_PLAY_IMPS)) ok=1; } if (!ok) { ss=*p; free(*path);*path=NULL; najdi_cestu(*p,tosect,SD_PLAY_IMPS,path,0); if (*path==NULL) return ss; p=*path; n=p+1; a_touch(ss,i); } p++;n++; ok=0; } free(*path);*path=NULL; return tosect; } static unsigned int get_path_len(const word *w) { unsigned int i = 0; while (w[i]) ++i; return i; } void recall() { int tosect = 0; unsigned int max,i; int j; word *paths[POCET_POSTAV]; for(i=0;imsg==E_KEYBOARD) break_sleep=1; if (msg->msg==E_MOUSE) { MS_EVENT *ms; ms=get_mouse(msg); if (ms->event_type & (0x2+0x8+0x20)) break_sleep=1; } } void sleep_players(va_list args) { int i; int hours=0; char reg; char enablity; if (!sleep_ticks) return; if (!GlobEvent(MAGLOB_STARTSLEEP,viewsector,viewdir)) return; enablity=enable_sound(0); mute_all_tracks(0); autosave(); insleep=1; update_mysky(); schovej_mysku(); curcolor=0;bar32(0,17,639,360+16); send_message(E_ADD,E_KEYBOARD,key_break_sleep); ukaz_mysku(); showview(0,0,0,0); unwire_proc(); break_sleep=0; while (sleep_ticks && !break_sleep) { reg=0; if (!(sleep_ticks%6)) { if ((reg=(sleep_ticks%HODINA==0))==1) { char s[50]; for(i=0;imsg==E_KEYBOARD) { c=quit_request_as_escape(va_arg(msg->data, int)); while (_bios_keybrd(_KEYBRD_READY) ) _bios_keybrd(_KEYBRD_READ); switch (c >> 8) { case 'H':step_zoom(0);break; case 'P':step_zoom(2);break; case 'M':if (get_control_key_state() & 0x80) step_zoom(1); else turn_zoom(1); break; case 'K':if (get_control_key_state() & 0x80) step_zoom(3); else turn_zoom(-1); break; case 79: case 's':step_zoom(3);break; case 81: case 't':step_zoom(1);break; case 0x21:if (q_item(flute_item,viewsector)) bott_draw_fletna(); break; case 57:a_touch(viewsector,viewdir);if (cur_mode==MD_PRESUN)send_message(E_KEYBOARD,28*256);break; case 15: case 50: if (GlobEvent(MAGLOB_BEFOREMAPOPEN,viewsector,viewdir)) show_automap(1); break; case 0x17:unwire_proc(); wire_inv_mode(human_selected);break; // case 'A':lodka=!lodka;set_backgrnd_mode(lodka);break; case 1:konec(0,0,0,0,0);break; // case 25:GamePause();break; case 28:enforce_start_battle();break; case 82:group_all();break; case '<':if (!battle && GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir)) {unwire_proc();cancel_render=1;wire_save_load(1);}break; case '=':unwire_proc();cancel_render=1;wire_save_load(0);break; case '>':game_setup(0,0,0,0,0);break; case 0x2E: if (get_control_key_state() && get_shift_key_state()) { console_show(!console_is_visible()); } break; CASE_KEY_1_6:c=group_sort[(c >> 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); break; /* default: { char s[20]; bott_disp_text(itoa(c,s,10)); break; }*/ } } } void start_dialog(int dialog,int mob) { if (battle) { call_dialog(dialog,mob); } else { force_start_dialog=1; start_dialog_number=dialog; start_dialog_mob=mob; } // call_dialog(dialog,mob); } int postavy_propadnout(int sector) { char redraw=0; int i,z=sector; mute_hit_sound=0; if (map_coord[sector].flags & MC_DPLAYER && map_sectors[sector].sector_type==S_DIRA) { for(i=0;i