gates_of_skeldal/game/realgame.c
2025-01-29 14:22:27 +01:00

1965 lines
49 KiB
C

#include <platform.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <strlite.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#include "inicfg.h"
#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[]="<BLOCK>";
char datapath;
D_ACTION *d_action={NULL};
int end_ptr;
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;
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,void *decomp,int class)
{
char *p,*end;
end=names+size;
p=names;
while (p<end)
{
def_handle(*ofs,p,decomp,class);
p=strchr(p,'\0');
p++;
(*ofs)++;
}
}
static void preload_percent(int cur,int max)
{
int pos;
pos=cur*640/max;
if (pos>640) pos=640;
curcolor=RGB555(16,16,16);hor_line32(0,476,pos);
curcolor=RGB555(8,8,8);hor_line32(0,477,pos);
curcolor=RGB555(31,31,31);hor_line32(0,475,pos);
showview(0,460,640,20);
do_events();
}
void preload_objects(int ofsts)
//#pragma preload_objects parm [];
{
int i;
char lodka=1;
char c[200];
for(i=1;i<mapsize;i++) if (map_sectors[i].sector_type==S_LODKA) break;
if (i==mapsize) lodka=0;
sprintf(c,"%sLOADING.MUS",pathtable[SR_WORK]);
// change_music(c);
trans_bar(0,460,640,20,0);
position(0,460);
set_font(H_FBOLD,RGB555(0,31,0));
sprintf(c,texty[TX_LOAD],mglob.mapname);
outtext(c);
for(i=0;i<ofsts;i++)
{
if (i<H_LODKA0 || i>H_LODKA7 || lodka) apreload_sign(i,ofsts);
}
apreload_start(preload_percent);
/* for(i=0;i<ofsts;i++)
{
ablock(ofsts-i-1);
preload_percent(i+ofsts,ofsts);
}
*/
}
int load_level_texts(char *filename)
{
int err;
level_texts=create_list(10);
err=load_string_list_ex(&level_texts,filename);
return err;
}
char *pripona(char *filename,char *pripona)
{
char *buff;
char *c;
buff=getmem(strlen(filename)+strlen(pripona)+2);
strcpy(buff,filename);
c=strrchr(buff,PATH_SEPARATOR_CHR);
if (c==NULL) c=buff;
c=strchr(c,'.');
if (c!=NULL) *c=0;
strcat(buff,pripona);
return buff;
}
void show_loading_picture(char *filename)
{
void *p;
int32_t s;
p=afile(filename,SR_BGRAFIKA,&s);
put_picture(0,0,p);
showview(0,0,0,0);
free(p);
#ifdef LOGFILE
display_ver(639,0,2,0);
#endif
cancel_pass=1;
}
extern int snd_devnum;
int load_map(char *filename)
{
FILE *f;
void *temp;
int sect;
int32_t size,r;
char nmapend=1;
int ofsts=START_HANDLE;
char *c,*d;
char snd_load=0;
void *mob_template;
int32_t mob_size;
int suc;
map_with_password=0;
c=find_map_path(filename);
schovej_mysku();
if (level_preload) show_loading_picture("LOADING.HI");
change_music("?");
zobraz_mysku();
f=fopen_icase(c,"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);
strupr(level_fname);
mob_template=NULL;
mob_size=0;
if (f==NULL) return -1;
if (snd_devnum==DEV_DAC) stop_mixing();
do
{
r=load_section(f,&temp,&sect,&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;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));
if (level_preload) preload_objects(ofsts);
end_ptr=ofsts;
d=pripona(c,".TXT");
free(c);
suc=load_level_texts(d);free(d);
if (!suc && level_texts!=NULL) create_playlist(level_texts[0]);
init_tracks();
change_music(get_next_music_from_playlist());
for(r=0;r<mapsize*4;r++) flag_map[r]=(char)map_sides[r].flags;
if (!doNotLoadMapState && load_map_state()==-2)
{
closemode();
display_error("Bug in temp file. Please purge some status blocks in last load savegame file.");
exit(0);
}
doNotLoadMapState=0;
if (snd_devnum==DEV_DAC) start_mixing();
return suc;
}
void add_leaving_place(int sector)
{
char *s;
concat(s,level_fname, ".lplace");
temp_storage_store(s, &sector, sizeof(sector));
}
int set_leaving_place(void)
{
return get_leaving_place(level_fname);
}
int get_leaving_place(char *level_name)
{
char *s;
concat(s,level_fname, ".lplace");
int sector;
if (temp_storage_retrieve(s, &sector, sizeof(sector))<0) {
return 0;
}
return sector;
}
void leave_current_map()
{
int i;
TFLY *p;
SEND_LOG("(GAME) Leaving current map ... start");
add_leaving_place(viewsector);
kill_all_sounds();
remove_all_mob_spells();
regen_all_mobs();
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;}
calc_fly();
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;i<mapsize*4;i++) if (map_items[i]!=NULL) free(map_items[i]);
free(map_items);
map_items=NULL;
}
for(i=0;i<hl_ptr;i++)
{
THANDLE_DATA *h;
h=get_handle(i);
if (h->loadproc==pcx_fade_decomp) zneplatnit_block(i);
}
for(i=hl_ptr;i<end_ptr;i++) undef_handle(i);
build_all_players();
purge_playlist();
hold_timer(TM_BACK_MUSIC,0);
mapsize=0;
free(level_fname);level_fname=NULL;
}
int32_t actn_flags(TSTENA *q,int32_t flags)
{
flags>>=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()
{
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;i<mapsize*4;i++)
{
TSTENA *p;
int pj,pk,sj,sk;
p=&map_sides[i];
sound_side_flags=p->flags;
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;
for(i=0;!postavy[i].groupnum || !postavy[i].used;i++);
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;i<POCET_POSTAV;i++)
{
psec=postavy[i].sektor;
for(j=0;j<pp;j++) if (sectors[j]==psec) break;
if (j==pp)
{
}
}
}
*/
static void akce_voda(THUMAN *h,int mode)
{
int ziv=mode?10:1;
if (h->kondice) 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) {
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) {bott_draw(0);return;}
cur_group=p->groupnum;
for(i=0;i<POCET_POSTAV;i++) if (!postavy[i].lives && postavy[i].groupnum!=cur_group) postavy[i].groupnum=0;
viewsector=p->sektor;
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;i<POCET_POSTAV && t<POCET_POSTAV;i++)
{
for(j=0;j<POCET_POSTAV;j++) if (postavy[j].groupnum==i+1) group_sort[t++]=j;
}
j=0;
while (t<POCET_POSTAV)
{
while (postavy[j].groupnum) j++;
group_sort[t++]=j++;
}
}
else
for(i=0;i<POCET_POSTAV;i++) group_sort[i]=i;
}
void add_to_group(int num)
{
if (lodka)return;
if (!postavy[num].used) return;
if (postavy[num].groupnum!=cur_group) postavy[num].groupnum=cur_group;
else if (!postavy[num].lives) postavy[num].groupnum=0;else
{
char cisla[7];
int i;
memset(cisla,0,sizeof(cisla));
for(i=0;i<POCET_POSTAV;i++) cisla[postavy[i].groupnum]=1;
for(i=1;i<7 && cisla[i]!=0;i++);
if (i==7) return;
postavy[num].groupnum=i;
}
}
void group_all(void)
{
char c=1;
int i;
THUMAN *h;
while (chod_s_postavama(1)) c=0;
if (c)
{
if (cur_group!=1)
{
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++) if (h->used && h->groupnum==1 && h->sektor!=viewsector) break;
if (i==POCET_POSTAV) cur_group=1;
}
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && 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;i<POCET_POSTAV;i++) map_coord[postavy[i].sektor].flags&=~(MC_DPLAYER | MC_SAFEPLACE);
}
void build_player_map() //je nutne volat po presunu postav
{
int i;
THUMAN *p;
for(i=0;p=&postavy[i],i<POCET_POSTAV;i++)
{
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;i<POCET_POSTAV;i++)
{
if (postavy[i].groupnum==cur_group)
{
postavy[i].sektor=viewsector;
postavy[i].direction=viewdir;
postavy[i].utek=1;
postavy[i].kondice-=weigth_defect(postavy+i);
if (postavy[i].kondice<0) postavy[i].kondice=0;
group_nums[cur_group]=1;
}
}
}
build_player_map();
SEND_LOG("(GAME) New position %d:%d",viewsector,viewdir);
return gatt;
}
void shift_zoom(char smer)
{
if (cancel_pass) return;
hold_timer(TM_BACK_MUSIC,1);
switch (smer & 3)
{
case 0:if (lodka)zooming_forward(ablock(H_LODKA));
else zooming_forward(ablock(H_BGR_BUFF));
break;
case 1:turn_left();break;
case 2:if (lodka)zooming_backward(ablock(H_LODKA));
else zooming_backward(ablock(H_BGR_BUFF));
break;
case 3:turn_right();break;
}
hold_timer(TM_BACK_MUSIC,0);
}
void hide_ms_at(int line)
{
if (ms_last_event.y<line)
{
update_mysky();
schovej_mysku();
}
}
void real_krok(EVENT_MSG *msg,void **data)
{
if (msg->msg==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;i<POCET_POSTAV;i++) if (postavy[i].sektor==0 && postavy[i].used)
{
postavy[i].lives=0;
player_check_death(postavy+i,0);
}
}
static void tele_redraw()
{
if (!running_anm) return;
redraw_scene();
calc_animations();
showview(0,17,640,360);
}
void postavy_teleport_group(int sector,int dir,int postava,char ef_mode)
{
int i;
i=mob_map[sector];
if (i)
{
mobs[--i].vlajky &= ~MOB_LIVE;
if ((i=mobs[i].next)!=0)
mobs[--i].vlajky &= ~MOB_LIVE;
mob_map[sector]=0;
}
destroy_player_map();
for(i=0;i<POCET_POSTAV;i++) if (postava & (1<<i))
{
if (ef_mode)
{
add_spectxtr(postavy[i].sektor,H_TELEP_PCX,14,1,0);
play_sample_at_sector(H_SND_TELEPOUT,viewsector,viewsector,0,0);
}
postavy[i].sektor=sector;
postavy[i].direction=dir;
if (!sector) player_hit(postavy+i,postavy[i].lives,0);
if (ef_mode)
{
add_spectxtr(sector,H_TELEP_PCX,14,1,0);
play_sample_at_sector(H_SND_TELEPOUT,viewsector,sector,0,0);
}
ef_mode=0;
}
build_player_map();
}
void postavy_teleport_effect(int sector,int dir,int postava,char effect)
{
char kolo=global_anim_counter;
int counter=0;
static int zavora=0;
if (zavora) return;
if (effect)
{
void *c;
zavora=1;
c=wire_proc;
unwire_proc();
recalc_volumes(viewsector,viewdir);
add_to_timer(-1,gamespeed,-1,tele_redraw);
add_spectxtr(viewsector,H_TELEP_PCX,14,1,0);
while (running_anm) do_events();
play_sample_at_channel(H_SND_TELEPIN,2,100);
play_big_mgif_animation(H_TELEPORT);
while (!running_anm) task_sleep();
kolo=global_anim_counter;
if (norefresh)
{
norefresh=0;
cancel_pass=1;
}
while (running_anm)
{
do_events();
if (kolo!=global_anim_counter)
{
counter+=(char)(global_anim_counter-kolo);
kolo=global_anim_counter;
if (counter==6)
{
postavy_teleport_group(sector,dir,postava,0);
viewsector=sector;
viewdir=dir&0x3;
recalc_volumes(viewsector,viewdir);
}
}
}
kolo=global_anim_counter;
while (kolo!=global_anim_counter) do_events();
delete_from_timer(-1);
wire_proc();
wire_proc=c;
cancel_render=1;
}
else
{
postavy_teleport_group(sector,dir,postava,1);
viewsector=sector;
viewdir=dir&0x3;
}
zavora=0;
}
void check_postavy_teleport()
{
int nsect=viewsector;
if (ISTELEPORTSECT(viewsector))
{
int i,ss=0,sid=viewsector*4+viewdir;
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].sektor==viewsector && postavy[i].used) ss|=1<<i;
if (map_sides[sid].flags & SD_SEC_VIS)
postavy_teleport_effect(map_sectors[viewsector].sector_tag,map_sectors[nsect].side_tag,ss,1);
else
postavy_teleport_group(viewsector=map_sectors[viewsector].sector_tag,viewdir=map_sectors[nsect].side_tag,ss,0);
}
}
static char test_can_walk(int grp)
{
int i;
THUMAN *h;
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && 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 (!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;i<POCET_POSTAV;i++,h++) if (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();
shift_zoom(smer);
if (smer==0 && nopass) shift_zoom(smer+2);
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;
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);
recalc_volumes(viewsector,viewdir);
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;
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;
unsigned int max,i;
int j;
word *paths[POCET_POSTAV];
for(i=0;i<POCET_POSTAV;i++)
{
if (postavy[i].groupnum==cur_group) tosect=postavy[i].sektor;
paths[i]=NULL;
}
for(i=0;i<POCET_POSTAV;i++)
if (postavy[i].sektor!=tosect) najdi_cestu(postavy[i].sektor,tosect,SD_PLAY_IMPS,&paths[i],0);
do
{
max=0xffff;j=-1;
unsigned int l;
for(i=0;i<POCET_POSTAV;i++) if (paths[i]!=NULL && (l=get_path_len(paths[i]))<(unsigned)max)
{
max=l;
j=i;
}
if (j!=-1)
{
postavy[j].sektor=check_path(&paths[j],tosect);
free(paths[j]);paths[j]=NULL;
bott_draw(1);
other_draw();
showview(0,0,0,0);
}
}
while (j!=-1);
}
void key_break_sleep(EVENT_MSG *msg,void **unused)
{
unused;
if (msg->msg==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;i<POCET_POSTAV;i++)
break_sleep|=sleep_regenerace(&postavy[i]);
update_mysky();
schovej_mysku();
bott_draw(0);
curcolor=0;bar32(0,120,639,140);
sprintf(s,texty[71],hours++);
set_font(H_FBOLD,RGB555(31,31,0));
set_aligned_position(320,130,1,1,s);outtext(s);
other_draw();
ukaz_mysku();
showview(0,120,640,20);
showview(0,378,640,102);
task_wait_event(E_TIMER);
task_wait_event(E_TIMER);
task_wait_event(E_TIMER);
task_wait_event(E_TIMER);
}
sleep_enemy(reg);
check_players_place(0);
}
if (battle) break_sleep|=1;
for(i=0;i<POCET_POSTAV;i++)
{
break_sleep|=check_jidlo_voda(&postavy[i])|check_map_specials(&postavy[i]);
}
send_message(E_KOUZLO_KOLO);
sleep_ticks--;
tick_tack(1);
if (!TimerEvents(viewsector,viewdir,game_time)) break;
}
send_message(E_DONE,E_KEYBOARD,key_break_sleep);
wire_proc();
bott_draw(1);
insleep=0;
enable_sound(enablity);
GlobEvent(MAGLOB_ENDSLEEP,viewsector,viewdir);
}
void *game_keyboard(EVENT_MSG *msg,void **usr)
{
uint8_t c;
usr;
if (pass_zavora) return NULL;
if (cur_mode==MD_END_GAME) return NULL;
if (msg->msg==E_KEYBOARD)
{
c=va_arg(msg->data, int)>>8;
while (_bios_keybrd(_KEYBRD_READY) ) _bios_keybrd(_KEYBRD_READ);
switch (c)
{
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_KEY_1_6:c=group_sort[c-2];
if (postavy[c].sektor==viewsector && postavy[c].used)
add_to_group(c);
zmen_skupinu(postavy+c);
bott_draw(1);
break;
/* default:
{
char s[20];
bott_disp_text(itoa(c,s,10));
break;
}*/
}
}
return &game_keyboard;
}
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<POCET_POSTAV;i++) if (postavy[i].sektor==sector && postavy[i].used && (postavy[i].vlastnosti[VLS_KOUZLA] & SPL_LEVITATION)==0)
{
int l=postavy[i].vlastnosti[VLS_MAXHIT];
z=postavy[i].sektor=map_sectors[sector].sector_tag;
if (postavy[i].groupnum==cur_group) viewsector=z;
if (z) player_hit(postavy+i,rnd(l/2)+l/3,0);else player_hit(postavy+i,postavy[i].lives,0);
redraw=1;
}
if (redraw) bott_draw(1);
}
return z;
}