mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-15 02:36:40 -04:00
2442 lines
63 KiB
C
2442 lines
63 KiB
C
#include <skeldal_win.h>
|
|
#include <bios.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <event.h>
|
|
#include <conio.h>
|
|
#include <zvuk.h>
|
|
#include <bgraph.h>
|
|
#include <bmouse.h>
|
|
#include <mem.h>
|
|
#include <malloc.h>
|
|
#include <memman.h>
|
|
#include <math.h>
|
|
#include "globals.h"
|
|
|
|
#define PRG_COLOR RGB555(0,31,31)
|
|
#define PRG_HELP_COLOR RGB555(31,31,0)
|
|
|
|
TMOB *attack_mob;
|
|
short init_distance;
|
|
short init_sector;
|
|
short select_player=-1;
|
|
char running_battle=0;
|
|
char att_player;
|
|
char pgm_help;
|
|
char death_play;char far_play;
|
|
short cislo_potvory;
|
|
short cislo_kola;
|
|
HUM_ACTION spell_string;
|
|
short caster;
|
|
short vybrana_zbran=-1;
|
|
char plr_switcher[POCET_POSTAV];
|
|
static autostart_round=0;
|
|
|
|
char autoattack=0;
|
|
char immortality=0;
|
|
long level_map[]=
|
|
{400, //level 2
|
|
1000, // 3
|
|
1800, // 4
|
|
2800, // 5
|
|
5000, // 6
|
|
8400, // 7
|
|
13000, // 8
|
|
20000, // 9
|
|
30000, // 10
|
|
45000, // 11
|
|
70000, // 12
|
|
110000, // 13
|
|
180000, // 14
|
|
300000, // 15
|
|
500000, // 16
|
|
800000, // 17
|
|
1300000, // 18
|
|
2000000, // 19
|
|
3000000, // 20
|
|
4500000, // 21
|
|
6500000, // 22
|
|
10000000, // 23
|
|
11000000, // 24
|
|
13000000, // 25
|
|
16000000, // 26
|
|
20000000, // 27
|
|
25000000, // 28
|
|
32000000, // 29
|
|
40000000, // 30
|
|
50000000, // 31
|
|
60000000, // 32
|
|
70000000, // 33
|
|
80000000, // 34
|
|
90000000, // 35
|
|
100000000, // 36
|
|
110000000, // 37
|
|
120000000, // 38
|
|
130000000, // 39
|
|
140000000, // 40
|
|
0x7fffffff // Immortal!
|
|
};
|
|
|
|
#define MAX_WEAPON_SKILL 10
|
|
|
|
word weapon_skill[]= //tabulka poctu uspesnych zasahu pro kazdy level
|
|
{
|
|
20, //level 1
|
|
40, // 2
|
|
80, // 3
|
|
160, // 4
|
|
320, // 5
|
|
640, // 6
|
|
1280, // 7
|
|
2560, // 8
|
|
5120, // 9
|
|
10240, // 10
|
|
65535, // max
|
|
};
|
|
|
|
char JePozdrzeno();
|
|
char mask_click(int id,int xa,int ya,int xr,int yr);
|
|
char mask_click_help(int id,int xa,int ya,int xr,int yr);
|
|
char mask_click_help_clear(int id,int xa,int ya,int xr,int yr);
|
|
char souboje_clk_throw(int id,int xa,int ya,int xr,int yr);
|
|
char runes_mask(int id,int xa,int ya,int xr,int yr);
|
|
char cancel_runes(int id,int xa,int ya,int xr,int yr);
|
|
char power(int id,int xa,int ya,int xr,int yr);
|
|
char cancel_power(int id,int xa,int ya,int xr,int yr);
|
|
char ask_who_proc(int id,int xa,int ya,int xr,int yr);
|
|
void wire_programming();
|
|
void souboje_vybrano(int d);
|
|
void program_draw();
|
|
|
|
void (*after_spell_wire)();
|
|
|
|
short *poradi=NULL;
|
|
short *prave_hraje;
|
|
|
|
void wire_programming();
|
|
void unwire_programming();
|
|
void wire_jadro_souboje();
|
|
void unwire_jadro_souboje();
|
|
|
|
char sel_zivel=0;
|
|
static char prekvapeni=0;
|
|
char powers[3]={0,1,2};
|
|
HUM_ACTION *magic_data;
|
|
|
|
static int minwait=0,maxwait=-1;
|
|
|
|
#define CLK_SOUBOJE 15
|
|
T_CLK_MAP clk_souboje[]=
|
|
{
|
|
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
|
|
{-1,87,0,142,14,game_setup,2,H_MS_DEFAULT},
|
|
{-1,30,0,85,14,konec,2,H_MS_DEFAULT},
|
|
{1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT},
|
|
{0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT},
|
|
{-1,291,0,313,14,go_book,2,H_MS_DEFAULT},
|
|
{-1,528,378,630,479,mask_click,2,-1},
|
|
{1,320,303,639,376,pick_item_,2,-1},//344
|
|
{0,0,303,320,376,pick_item_,2,-1},//344
|
|
{3,0,200,320,340,pick_item_,2,-1},//303
|
|
{2,320,200,639,340,pick_item_,2,-1},//303
|
|
{-1,528,378,630,479,mask_click_help,1,-1},
|
|
{-1,0,0,640,480,mask_click_help_clear,1,-1},
|
|
{MS_GAME_WIN,0,17,639,377,souboje_clk_throw,2,-1},
|
|
{-1,54,378,497,479,start_invetory,2+8,-1},
|
|
};
|
|
|
|
|
|
char clk_enter(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
int i=28*256;
|
|
id;xa;ya;xr;yr;
|
|
send_message(E_KEYBOARD,i);
|
|
return 0;
|
|
}
|
|
|
|
|
|
char clk_battle_touch(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
int i;
|
|
side_touched=0;
|
|
i=clk_touch(id,xa,ya,xr,yr);
|
|
if (side_touched) clk_enter(id,xa,ya,xr,yr);
|
|
return i;
|
|
}
|
|
|
|
#define CLK_PRESUN 12
|
|
T_CLK_MAP clk_presun[]=
|
|
{
|
|
{H_SIPKY_S,561,378,598,407,clk_step,2,H_MS_DEFAULT},
|
|
{H_SIPKY_SZ,530,387,560,418,clk_step,2,H_MS_DEFAULT},
|
|
{H_SIPKY_Z,529,419,555,453,clk_step,2,H_MS_DEFAULT},
|
|
{H_SIPKY_J,560,446,598,474,clk_step,2,H_MS_DEFAULT},
|
|
{H_SIPKY_SV,599,387,628,418,clk_step,2,H_MS_DEFAULT},
|
|
{H_SIPKY_V,605,420,632,454,clk_step,2,H_MS_DEFAULT},
|
|
{MS_GAME_WIN,0,17,639,377,clk_battle_touch,2,-1},
|
|
//{3,109,303,320,340,pick_item_,2,-1},
|
|
//{2,320,303,531,340,pick_item_,2,-1},
|
|
//{1,320,344,577,376,pick_item_,2,-1},
|
|
//{0,63,344,320,376,pick_item_,2,-1},
|
|
//{MS_GAME_WIN,0,17,639,377,clk_throw,2,-1},
|
|
//{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
|
|
{1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT},
|
|
{0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT},
|
|
{-1,30,0,85,14,konec,2,H_MS_DEFAULT},
|
|
{-1,565,408,593,447,clk_enter,2,H_MS_DEFAULT},
|
|
{-1,0,0,640,480,empty_clk,0xff,-1},
|
|
};
|
|
|
|
#define CLK_RUNES 3
|
|
T_CLK_MAP clk_runes[]=
|
|
{
|
|
{-1,520,378,639,479,runes_mask,2+1,H_MS_DEFAULT},
|
|
{-1,0,0,639,479,cancel_runes,0x8,H_MS_DEFAULT},
|
|
{-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT},
|
|
};
|
|
|
|
|
|
#define CLK_POWER 5
|
|
#define CLK_POWER_WHO 7
|
|
T_CLK_MAP clk_power[]=
|
|
{
|
|
{0,535,391,637,411,power,2,H_MS_DEFAULT},
|
|
{1,535,421,637,441,power,2,H_MS_DEFAULT},
|
|
{2,535,431,637,471,power,2,H_MS_DEFAULT},
|
|
{-1,0,0,639,377,cancel_power,2+8,-1},
|
|
{-1,0,378,639,479,cancel_power,8,-1},
|
|
{-1,54,378,497,479,ask_who_proc,2,-1},
|
|
{-1,0,0,639,479,empty_clk,0xff,-1},
|
|
};
|
|
|
|
|
|
THUMAN *isplayer(int sector,THUMAN *h,char death)
|
|
{
|
|
short c=map_coord[sector].flags;
|
|
if (c & MC_PLAYER || (death && c & MC_DEAD_PLR))
|
|
{
|
|
if (h==NULL) h=postavy;else h++;
|
|
while (h-postavy<POCET_POSTAV)
|
|
{
|
|
if (h->used && (h->lives || death) && h->sektor==sector) return h;
|
|
h++;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int numplayers(int sector,char death)
|
|
{
|
|
int i,c;
|
|
THUMAN *h;
|
|
|
|
for(i=0,c=0,h=postavy;i<POCET_POSTAV;i++,h++) if (h->used && (death || h->lives) && h->sektor==sector) c++;
|
|
return c;
|
|
}
|
|
|
|
TMOB *ismonster(int sector,TMOB *m)
|
|
{
|
|
if (mob_map[sector])
|
|
{
|
|
if (m==NULL) m=mobs+mob_map[sector]-1;else
|
|
if (m->next) m=mobs+m->next-1;else return NULL;
|
|
}
|
|
else m=NULL;
|
|
return m;
|
|
}
|
|
|
|
void presun_krok(EVENT_MSG *msg,void **user)
|
|
{
|
|
user;
|
|
if (msg->msg==E_INIT) return;
|
|
if (msg->msg==E_DONE) return;
|
|
postavy[select_player].actions--;
|
|
if (hromadny_utek)
|
|
{
|
|
int i;
|
|
destroy_player_map();
|
|
for (i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].lives && postavy[i].sektor==hromadny_utek)
|
|
postavy[i].sektor=postavy[select_player].sektor;
|
|
build_player_map();
|
|
hromadny_utek=postavy[select_player].sektor;
|
|
}
|
|
msg->msg=-1;
|
|
}
|
|
|
|
void poloz_vsechny_predmety()
|
|
{
|
|
int i;
|
|
|
|
for(i=0;i<POCET_POSTAV && picked_item!=NULL;i++) //polozeni pripadne drzene veci v mysi.
|
|
if (postavy[i].used && postavy[i].sektor==viewsector && put_item_to_inv(&postavy[i],picked_item))
|
|
{
|
|
free(picked_item);
|
|
picked_item=NULL;
|
|
}
|
|
if (picked_item!=NULL)
|
|
{
|
|
push_item(viewsector,viewdir,picked_item);
|
|
free(picked_item);
|
|
picked_item=NULL;
|
|
}
|
|
pick_set_cursor();
|
|
}
|
|
|
|
char q_zacit_souboj(TMOB *p,int d,short sector)
|
|
{
|
|
int ss;
|
|
int i;
|
|
|
|
if (p->vlastnosti[VLS_KOUZLA] & (SPL_STONED | SPL_FEAR)) return 0;
|
|
dsee++;
|
|
// if (battle) return 1;
|
|
prekvapeni=0;
|
|
if (d>p->dosah) return 0;
|
|
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].sektor==sector && postavy[i].direction==((p->dir+2)&0x3)) break;
|
|
if (i==POCET_POSTAV) prekvapeni=!battle;
|
|
if (d==1)
|
|
{
|
|
ss=map_sectors[p->sector].step_next[p->dir];
|
|
if (!(map_coord[ss].flags & MC_PLAYER)) return 0;
|
|
}
|
|
if (battle && p->vlajky & MOB_CASTING && get_spell_track(p->casting)) return 1;
|
|
if (d!=1)
|
|
{
|
|
if (prekvapeni) return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void zacni_souboj(TMOB *p,int d,short sector)
|
|
{
|
|
int i;
|
|
//toto je jen test
|
|
battle=1;
|
|
attack_mob=p;
|
|
init_distance=d;
|
|
init_sector=sector;
|
|
map_coord[p->sector].flags |= MC_AUTOMAP;
|
|
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].sektor==init_sector) break;
|
|
if (i<POCET_POSTAV) att_player=i;else att_player=0xff;
|
|
}
|
|
|
|
|
|
|
|
int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int bonusplus)
|
|
{
|
|
int zasah,mutok,flg;
|
|
flg=obrance[VLS_KOUZLA];
|
|
if (game_extras & EX_ALTERNATEFIGHT)
|
|
{
|
|
int postih=(chaos+1)/2;
|
|
int testutok=rangrnd(utocnik[VLS_UTOK_L],utocnik[VLS_UTOK_H])+utocnik[VLS_OBRAT]/4+bonusplus;
|
|
int testobrana=rangrnd(obrance[VLS_OBRAN_L],obrance[VLS_OBRAN_H])+obrance[VLS_OBRAT]/(4*postih)+(flg & SPL_INVIS?rangrnd(5,15):0);
|
|
int utok=rangrnd(utocnik[VLS_UTOK_L],utocnik[VLS_UTOK_H])+utocnik[VLS_SILA]/10+bonusplus;
|
|
int obrana=rangrnd(obrance[VLS_OBRAN_L],obrance[VLS_OBRAN_H])+obrance[VLS_OBRAT]/(10*postih);
|
|
int zv;
|
|
mutok=rangrnd(utocnik[VLS_MGSIL_L],utocnik[VLS_MGSIL_H]);
|
|
dhit=testutok;
|
|
ddef=testobrana;
|
|
if (testutok<testobrana) utok=obrana=0;
|
|
else
|
|
{
|
|
dhit=utok;
|
|
ddef=obrana;
|
|
}
|
|
zv=obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]];
|
|
zv=mgochrana(zv);
|
|
mutok=zv*mutok/100;
|
|
if (rnd(obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]]/2)>mutok) mutok=0;
|
|
dmzhit=mutok;
|
|
zasah=utok-obrana;
|
|
}
|
|
else
|
|
{
|
|
int utok,obrana;
|
|
int ospod;
|
|
int x,y,z,zv;
|
|
|
|
chaos=(chaos+1)/2;
|
|
ospod=obrance[VLS_OBRAN_L]/chaos;
|
|
x=rnd(utocnik[VLS_UTOK_H]-utocnik[VLS_UTOK_L]+1);
|
|
y=rnd(obrance[VLS_OBRAN_H]-ospod+1);
|
|
z=rnd(utocnik[VLS_MGSIL_H]-utocnik[VLS_MGSIL_L]+1);
|
|
dhit=utok=utocnik[VLS_UTOK_L]+x+(utocnik[VLS_SILA]*15+(utocnik[VLS_OBRAT])*10)/150+bonusplus;
|
|
obrana=ospod+y+(obrance[VLS_OBRAT]/5)+(flg & SPL_INVIS?10:0);
|
|
mutok=utocnik[VLS_MGSIL_L]+z;
|
|
zv=obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]];
|
|
zv=mgochrana(zv);
|
|
mutok=zv*mutok/100;
|
|
dmzhit=mutok;
|
|
zasah=utok-(ddef=obrana);
|
|
}
|
|
if (zasah<0) zasah=0;
|
|
if (zasah>0) zasah+=utocnik[VLS_DAMAGE],zasah=max(zasah,1);
|
|
ddostal=zasah;
|
|
zasah=zasah+mutok;
|
|
if (zasah>0)
|
|
{
|
|
zasah+=zbran;
|
|
if (zasah<1) zasah=1;
|
|
}
|
|
if (flg & SPL_SANC) zasah/=2;
|
|
if (flg & SPL_HSANC) zasah/=4;
|
|
if (flg & SPL_TVAR) zasah=-zasah;
|
|
return zasah;
|
|
}
|
|
|
|
void rozhodni_o_poradi()
|
|
{
|
|
int celk=0;
|
|
int i,j;
|
|
short *r,mem;
|
|
|
|
for(i=0;i<MAX_MOBS;i++) if (mobs[i].vlajky & MOB_LIVE && mobs[i].vlajky & MOB_IN_BATTLE) celk+=mobs[i].actions;
|
|
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].used) celk+=postavy[i].programovano;
|
|
if (poradi!=NULL) free(poradi);
|
|
r=poradi=getmem(celk*2+4);
|
|
for(i=0;i<MAX_MOBS;i++) if (mobs[i].vlajky & MOB_LIVE && mobs[i].vlajky & MOB_IN_BATTLE)
|
|
{
|
|
for(j=0;j<mobs[i].actions;j++) *r++=i+1;
|
|
}
|
|
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].used)
|
|
{
|
|
for(j=0;j<postavy[i].programovano;j++) *r++=-i-1;
|
|
}
|
|
for(i=0;i<celk;i++)
|
|
{
|
|
j=rnd(celk);
|
|
mem=poradi[j];
|
|
poradi[j]=poradi[i];
|
|
poradi[i]=mem;
|
|
}
|
|
*r++=-255;
|
|
*r++=0;
|
|
prave_hraje=poradi;
|
|
}
|
|
void hrat_souboj()
|
|
{
|
|
static counter=0;
|
|
char cond=ms_last_event.y>378 && ms_last_event.x>510 && cur_mode!=MD_PRESUN;
|
|
if (cond) schovej_mysku();
|
|
redraw_scene();
|
|
if (!cancel_render && !norefresh)
|
|
{
|
|
if (cur_mode!=MD_PRESUN)
|
|
{
|
|
program_draw();
|
|
draw_blood(0,0,0);
|
|
check_players_place(0);
|
|
}
|
|
showview(0,0,0,0);
|
|
if (neco_v_pohybu==2) neco_v_pohybu=0; else neco_v_pohybu=2;
|
|
calc_fly();mob_animuj();
|
|
if (d_action!=NULL) do_delay_actions();
|
|
}
|
|
if (cond) ukaz_mysku();
|
|
if (neco_v_pohybu)
|
|
{
|
|
if (++counter>=maxwait && maxwait>0) neco_v_pohybu=0;
|
|
}
|
|
else
|
|
if (++counter<minwait) neco_v_pohybu=2;
|
|
if (!neco_v_pohybu)
|
|
{
|
|
if (JePozdrzeno()) neco_v_pohybu=1;
|
|
counter=0;
|
|
maxwait=-1;
|
|
minwait=0;
|
|
}
|
|
calc_animations();
|
|
}
|
|
|
|
void auto_group()
|
|
{
|
|
int i,j,t=1;
|
|
THUMAN *p,*q;
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
postavy[i].groupnum=0;
|
|
for(i=0;p=&postavy[i],i<POCET_POSTAV;i++)
|
|
if (!p->groupnum && p->lives)
|
|
{
|
|
p->groupnum=t++;
|
|
for(j=i+1;q=&postavy[j],j<POCET_POSTAV;j++)
|
|
if (p->sektor==q->sektor && p->direction==q->direction && q->used && q->lives)
|
|
q->groupnum=p->groupnum;
|
|
}
|
|
}
|
|
/*
|
|
int vyber_zacinajiciho(int att_player)
|
|
{
|
|
int gr;
|
|
THUMAN *p;
|
|
int i;
|
|
|
|
// if (att_player==0xff)
|
|
// for(i=0;i<pocet_postav;i++) if (postavy[i].groupnum==cur_group) att_player=i
|
|
for(gr=0;group_sort[gr]!=att_player;gr++);
|
|
i=0;
|
|
do
|
|
{
|
|
p=&postavy[group_sort[gr]];
|
|
gr+=(gr>=POCET_POSTAV?-POCET_POSTAV:1);
|
|
i++;
|
|
}
|
|
while ((!p->used || !p->actions)&& i<6);
|
|
return p-postavy;
|
|
}
|
|
|
|
int vyber_prvniho(int att)
|
|
{
|
|
int grp;
|
|
int i;
|
|
|
|
if (att==0xff)
|
|
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].groupnum==cur_group) att=i;
|
|
grp=postavy[att].groupnum;
|
|
for(i=0;postavy[group_sort[i]].groupnum!=grp;i++);
|
|
return i;
|
|
}
|
|
*/
|
|
static int vyber_hrace(int att)
|
|
{
|
|
int gr,i;
|
|
THUMAN *h;
|
|
|
|
if (att>POCET_POSTAV || att<0)
|
|
gr=cur_group,att=0xff;
|
|
else
|
|
gr=postavy[att].groupnum;
|
|
h=postavy;
|
|
for(i=0,h=postavy;i<POCET_POSTAV && (!h->used || !h->lives || !h->actions || h->groupnum!=gr) ;i++,h++);
|
|
if (i==6)
|
|
if (att!=0xff) return att;else return group_sort[0];
|
|
else
|
|
return i;
|
|
}
|
|
|
|
void zacatek_kola()
|
|
{
|
|
int i;
|
|
THUMAN *p;
|
|
|
|
SEND_LOG("(BATTLE) Start round",0,0);
|
|
build_player_map();
|
|
cislo_kola++;
|
|
autostart_round=0;
|
|
for(i=0;i<MAX_MOBS;i++) if (mobs[i].vlajky & MOB_LIVE)
|
|
{
|
|
mobs[i].actions=get_ap(mobs[i].vlastnosti);
|
|
mobs[i].walk_data=0;
|
|
}
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
{
|
|
p=&postavy[i];
|
|
if (p->used)
|
|
{
|
|
postavy[i].programovano=0;
|
|
if (p->kondice && p->lives)
|
|
{
|
|
p->actions=get_ap(p->vlastnosti);
|
|
// if (p->actions) autostart_round=0;
|
|
}
|
|
else postavy[i].actions=0;
|
|
if (postavy[i].zvolene_akce!=NULL)free(postavy[i].zvolene_akce);
|
|
postavy[i].zvolene_akce=NewArr(HUM_ACTION,postavy[i].actions+1);
|
|
memset(postavy[i].zvolene_akce,0,(postavy[i].actions+1)*sizeof(HUM_ACTION));
|
|
postavy[i].provadena_akce=postavy[i].zvolene_akce;
|
|
}
|
|
}
|
|
auto_group();
|
|
sort_groups();
|
|
select_player=vyber_hrace(att_player);
|
|
//att_player=vyber_prvniho(att_player);
|
|
//select_player=vyber_zacinajiciho(att_player);
|
|
zmen_skupinu(&postavy[select_player]);
|
|
viewsector=postavy[select_player].sektor;
|
|
viewdir=postavy[select_player].direction;
|
|
redraw_scene();cancel_render=1;
|
|
}
|
|
|
|
char check_end_game()
|
|
{
|
|
THUMAN *p;
|
|
int i;
|
|
char end=1;
|
|
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
{
|
|
p=&postavy[i];
|
|
if (p->used && p->lives)
|
|
{
|
|
end=2;
|
|
if (p->groupnum==cur_group) return 0;
|
|
}
|
|
}
|
|
return end;
|
|
}
|
|
|
|
void konec_kola()
|
|
{
|
|
int i;THUMAN *h;TMOB *m;
|
|
int j;
|
|
|
|
SEND_LOG("(BATTLE) End round",0,0);
|
|
prekvapeni=0;
|
|
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
|
|
if (h->used)
|
|
{
|
|
if (h->zvolene_akce!=NULL) free(h->zvolene_akce);
|
|
h->zvolene_akce=NULL;
|
|
h->programovano=0;
|
|
if (h->vlastnosti[VLS_KOUZLA] & SPL_REGEN && h->lives)
|
|
h->lives+=3;
|
|
player_check_death(h,1);
|
|
if (h->lives>h->vlastnosti[VLS_MAXHIT]) h->lives=h->vlastnosti[VLS_MAXHIT];
|
|
}
|
|
for(i=0,m=mobs;i<MAX_MOBS;i++,m++)
|
|
if (m->vlajky & MOB_LIVE && m->vlastnosti[VLS_KOUZLA] & SPL_REGEN)
|
|
{
|
|
m->lives+=3;if (m->lives>m->vlastnosti[VLS_MAXHIT]) m->lives=m->vlastnosti[VLS_MAXHIT];
|
|
}
|
|
auto_group();
|
|
sort_groups();
|
|
select_player=-1;
|
|
GlobEvent(MAGLOB_ONROUND,viewsector,viewdir);
|
|
sleep_ticks+=MAX_SLEEP/12;
|
|
if (sleep_ticks>MAX_SLEEP) sleep_ticks=MAX_SLEEP;
|
|
for(i=0,j=0;i<POCET_POSTAV;i++)
|
|
if (postavy[i].lives || ~postavy[i].vlastnosti[VLS_KOUZLA]&SPL_STONED)
|
|
{
|
|
if (i!=j)memcpy(&postavy[j++],&postavy[i],sizeof(postavy[i]));
|
|
else j++;
|
|
}
|
|
if (j<POCET_POSTAV) memset(&postavy[j],0,sizeof(THUMAN)*(POCET_POSTAV-j));
|
|
destroy_player_map();
|
|
tick_tack(1);
|
|
TimerEvents(viewsector,viewdir,game_time);
|
|
}
|
|
|
|
static void kbd_end_game(EVENT_MSG *msg,void *unused)
|
|
{
|
|
unused;
|
|
if (msg->msg==E_KEYBOARD && !pass_zavora)
|
|
{
|
|
msg->msg=-2;
|
|
delete_from_timer(TM_SCENE);
|
|
delete_from_timer(TM_FLY);
|
|
wire_save_load(2);
|
|
bott_draw(1);
|
|
cancel_render=1;
|
|
}
|
|
}
|
|
|
|
static char clk_goon(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
id,xa,ya,xr,yr;
|
|
send_message(E_KEYBOARD,13);
|
|
return 1;
|
|
}
|
|
|
|
#define CLK_END_GAME 2
|
|
T_CLK_MAP clk_end_game[]=
|
|
{
|
|
{-1,0,0,639,479,clk_goon,8+2,H_MS_DEFAULT},
|
|
{-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT},
|
|
};
|
|
|
|
|
|
EVENT_PROC(end_game_end_phase)
|
|
{
|
|
static wait=0;
|
|
WHEN_MSG(E_TIMER)
|
|
{
|
|
if (pass_zavora) return;
|
|
if (wait==2)
|
|
{
|
|
send_message(E_ADD,E_KEYBOARD,kbd_end_game);
|
|
send_message(E_DONE,E_TIMER,end_game_end_phase);
|
|
change_click_map(clk_end_game,CLK_END_GAME);
|
|
}
|
|
else wait++;
|
|
}
|
|
WHEN_MSG(E_INIT)
|
|
wait=0;
|
|
user_ptr;
|
|
}
|
|
|
|
void wire_end_game()
|
|
{
|
|
int i;
|
|
if (cur_mode==MD_END_GAME) return;
|
|
konec_kola();
|
|
battle=0;running_battle=0;
|
|
unwire_proc();
|
|
for(i=0;i<MAX_MOBS;i++) if (mobs[i].vlajky & MOB_LIVE) mobs[i].vlajky&=~MOB_IN_BATTLE;
|
|
bott_disp_text(texty[65]);
|
|
bott_text_forever();
|
|
add_to_timer(TM_SCENE,gamespeed,-1,refresh_scene);
|
|
add_to_timer(TM_FLY,gamespeed,-1,calc_fly);
|
|
disable_click_map();
|
|
send_message(E_ADD,E_TIMER,end_game_end_phase);
|
|
cur_mode=MD_END_GAME;
|
|
build_player_map();
|
|
GlobEvent(MAGLOB_ONDEADALL,viewsector,viewdir);
|
|
GlobEventList[MAGLOB_ONDEADALL].sector=0;
|
|
GlobEventList[MAGLOB_ONDEADALL].side=0;
|
|
}
|
|
|
|
|
|
void konec_presunu(EVENT_MSG *msg,void **unused)
|
|
{
|
|
unused;
|
|
|
|
if (msg->msg==E_KEYBOARD && ((*(int *)msg->data)>>8)==28 && !pass_zavora)
|
|
{
|
|
unwire_proc();
|
|
wire_jadro_souboje();
|
|
msg->msg=-1;
|
|
}
|
|
}
|
|
|
|
void wire_presun_postavy();
|
|
void unwire_presun_postavy()
|
|
{
|
|
disable_click_map();
|
|
send_message(E_DONE,E_KEYBOARD,game_keyboard);
|
|
send_message(E_DONE,E_KROK,presun_krok);
|
|
send_message(E_DONE,E_KEYBOARD,konec_presunu);
|
|
delete_from_timer(TM_SCENE);
|
|
cur_mode=MD_INBATTLE;
|
|
sort_groups();
|
|
wire_proc=wire_presun_postavy;
|
|
hromadny_utek=0;
|
|
}
|
|
|
|
void wire_presun_postavy()
|
|
{
|
|
unwire_proc();
|
|
|
|
moving_player=select_player;
|
|
change_click_map(clk_presun,CLK_PRESUN);
|
|
send_message(E_ADD,E_KEYBOARD,game_keyboard);
|
|
send_message(E_ADD,E_KROK,presun_krok);
|
|
send_message(E_ADD,E_KEYBOARD,konec_presunu);
|
|
cur_mode=MD_PRESUN;
|
|
auto_group();
|
|
sort_groups();
|
|
bott_draw(1);
|
|
redraw_scene();
|
|
add_to_timer(TM_SCENE,gamespeed,-1,hrat_souboj);
|
|
showview(0,0,0,0);
|
|
unwire_proc=unwire_presun_postavy;
|
|
cancel_render=1;
|
|
}
|
|
|
|
static DWORD SPozdrzeno=0;
|
|
|
|
static char JePozdrzeno()
|
|
{
|
|
return GetTickCount()<SPozdrzeno;
|
|
}
|
|
|
|
void pozdrz_akci()
|
|
{
|
|
int battlespeed=gamespeed-gamespeed*gamespeedbattle/5;
|
|
SPozdrzeno=GetTickCount()+battlespeed*2000/6;
|
|
}
|
|
|
|
/*void pozdrz_akci_proc(THE_TIMER *x)
|
|
{
|
|
x;
|
|
neco_v_pohybu=1;
|
|
}
|
|
|
|
void pozdrz_akci()
|
|
{
|
|
add_to_timer(0,1,75,pozdrz_akci_proc);
|
|
}
|
|
*/
|
|
void souboje_prezbrojeni(int postava)
|
|
{
|
|
unwire_proc();
|
|
bott_draw(1);
|
|
wire_inv_mode(&postavy[postava]);
|
|
battle_mode=MD_PREZBROJIT;
|
|
}
|
|
|
|
void prejdi_na_pohled(THUMAN *p)
|
|
{
|
|
viewsector=p->sektor;
|
|
viewdir=p->direction;
|
|
pozdrz_akci();
|
|
hold_timer(TM_SCENE,1);
|
|
redraw_scene();
|
|
cancel_render=1;
|
|
program_draw();
|
|
showview(0,0,0,0);
|
|
hold_timer(TM_SCENE,0);
|
|
|
|
}
|
|
|
|
int hromadny_utek;
|
|
static int UtekHromadne(int sector)
|
|
{
|
|
int minact=999;
|
|
int i;
|
|
int p=0;
|
|
for (i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].sektor==sector && postavy[i].kondice>2)
|
|
{
|
|
int wf=weigth_defect(postavy+i)+2;
|
|
if (postavy[i].provadena_akce==NULL || postavy[i].provadena_akce->action!=AC_RUN) return 0;
|
|
if (postavy[i].utek<minact) minact=postavy[i].utek;
|
|
if (postavy[i].kondice/wf<minact) minact=postavy[i].kondice/wf;
|
|
p++;
|
|
}
|
|
return p>1?minact:0;
|
|
}
|
|
|
|
void utek_postavy(THUMAN *p)
|
|
{
|
|
int minact=0;
|
|
p->actions=p->utek;
|
|
if (game_extras & EX_GROUP_FLEE && (minact=UtekHromadne(p->sektor))!=0)
|
|
{
|
|
int i;
|
|
p->actions=minact;
|
|
hromadny_utek=p->sektor;
|
|
for (i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].sektor==p->sektor)
|
|
{
|
|
int wf=weigth_defect(postavy+i)+2;
|
|
postavy[i].kondice-=minact*wf;
|
|
if (postavy[i].kondice<0) postavy[i].kondice=0;
|
|
if (postavy+i!=p) postavy[i].programovano=0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int wf=weigth_defect(p)+2;
|
|
hromadny_utek=0;
|
|
if (p->actions)
|
|
{
|
|
p->kondice-=p->actions*wf;
|
|
if (p->kondice<0)
|
|
{
|
|
p->actions+=p->kondice/wf;
|
|
p->kondice=0;
|
|
}
|
|
}
|
|
}
|
|
wire_presun_postavy();
|
|
prejdi_na_pohled(p);
|
|
}
|
|
|
|
int trace_path(sector,dir)
|
|
{
|
|
int mm,p,c=5;
|
|
int r=rnd(2);
|
|
do
|
|
{
|
|
if ((mm=mob_map[sector])!=0)
|
|
{
|
|
if (mobs[mm-1].stay_strategy & MOB_BIG) return 0;
|
|
if (mobs[mm-1].next!=0 && r==1) mm=mobs[mm-1].next;
|
|
switch (dir)
|
|
{
|
|
case 0: p=mobs[mm-1].locx-128;break;
|
|
case 1: p=mobs[mm-1].locy-128;break;
|
|
case 2: p=-(mobs[mm-1].locx-128);break;
|
|
case 3: p=-(mobs[mm-1].locy-128);break;
|
|
}
|
|
if (p<-12) return -24;
|
|
else if (p>12) return +24;
|
|
else return 0;
|
|
}/* return rnd(3)-1;*/
|
|
if (map_sides[(sector<<2)+dir].flags & SD_THING_IMPS) return -255;
|
|
sector=map_sectors[sector].step_next[dir];
|
|
c--;
|
|
}
|
|
while (c);
|
|
return -255;
|
|
}
|
|
|
|
void hod_dykou(THUMAN *p,int where,int bonus)
|
|
{
|
|
short *pp;
|
|
int i;
|
|
int ps;
|
|
LETICI_VEC *v;
|
|
|
|
ps=trace_path(p->sektor,p->direction);
|
|
if (ps==-255) return;
|
|
pp=picked_item;
|
|
picked_item=getmem(2*sizeof(short));
|
|
picked_item[0]=p->wearing[where];
|
|
picked_item[1]=0;
|
|
v=throw_fly(320,100,0);
|
|
v->ypos=ps;
|
|
v->hit_bonus=(p->vlastnosti[VLS_OBRAT]*3+p->vlastnosti[VLS_SILA]*2)/30+bonus;
|
|
v->damage=0;
|
|
for(i=0;i<p->inv_size;i++)
|
|
{
|
|
int it;
|
|
|
|
it=p->inv[i];
|
|
if (it--)
|
|
{
|
|
if (glob_items[it].druh==TYP_VRHACI && glob_items[it].umisteni==PL_RUKA)
|
|
{
|
|
p->wearing[where]=it+1;
|
|
p->inv[i]=0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(i==p->inv_size) p->wearing[where]=0;
|
|
picked_item=pp;
|
|
}
|
|
|
|
void vystrel_sip(THUMAN *p,int bonus)
|
|
{
|
|
short *pp;
|
|
int ps;
|
|
int i;
|
|
int x;
|
|
LETICI_VEC *v;
|
|
TITEM *t;
|
|
|
|
ps=trace_path(p->sektor,p->direction);
|
|
if (ps==-255) return;
|
|
if (!p->sipy)
|
|
{
|
|
char s[100];
|
|
|
|
sprintf(s,texty[72],p->jmeno);
|
|
bott_disp_text(s);
|
|
return;
|
|
}
|
|
for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].user_value==0) break;
|
|
if (i==item_count) return;
|
|
t=glob_items+i;
|
|
pp=picked_item;
|
|
picked_item=getmem(2*sizeof(short));
|
|
picked_item[0]=i+1;
|
|
picked_item[1]=0;
|
|
p->sipy--;
|
|
v=throw_fly(320,100,1);
|
|
v->ypos=ps;
|
|
x=rnd(p->vlastnosti[VLS_UTOK_H]-p->vlastnosti[VLS_UTOK_L]);
|
|
v->hit_bonus=x+p->vlastnosti[VLS_UTOK_L]+(p->vlastnosti[VLS_SILA]*10+p->vlastnosti[VLS_OBRAT]*15)/150+bonus;
|
|
v->damage=p->vlastnosti[VLS_DAMAGE];
|
|
picked_item=pp;
|
|
t->zmeny[VLS_MGSIL_H]=p->vlastnosti[VLS_MGSIL_H]; //adjust zmen v magickem utoku
|
|
t->zmeny[VLS_MGSIL_L]=p->vlastnosti[VLS_MGSIL_L];
|
|
t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL];
|
|
play_sample_at_sector(H_SND_SIP1+rnd(2),0,0,0,0);
|
|
neco_v_pohybu=1;
|
|
}
|
|
|
|
char is_useable_weapon(int i)
|
|
{
|
|
if (!i) return 0;
|
|
i--;
|
|
switch (glob_items[i].druh)
|
|
{
|
|
case TYP_UTOC:
|
|
case TYP_VRHACI:
|
|
case TYP_STRELNA:
|
|
case TYP_SVITEK:return 1;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
int select_weapon(THUMAN *p,char ask)
|
|
{
|
|
char lp,rp;
|
|
int li,ri;
|
|
char *c;
|
|
|
|
li=p->wearing[PO_RUKA_L];
|
|
ri=p->wearing[PO_RUKA_R];
|
|
lp=is_useable_weapon(li);
|
|
rp=is_useable_weapon(ri);
|
|
if (!lp && !rp) return 2;
|
|
if (lp && !rp) return 0;
|
|
if (!lp && rp) return 1;
|
|
li--;
|
|
ri--;
|
|
if (glob_items[li].druh==glob_items[ri].druh && glob_items[li].druh==TYP_UTOC) return 2;
|
|
if (!ask) return rnd(2);
|
|
unwire_proc();
|
|
c=alloca(strlen(p->jmeno)+strlen(texty[82])+1);
|
|
sprintf(c,texty[82],p->jmeno);
|
|
lp=message(2,0,1,"",c,texty[83],texty[84]);
|
|
wire_proc();
|
|
return lp;
|
|
}
|
|
|
|
static int vypocti_bonus(THUMAN *p,int vybrana_zbran)
|
|
{
|
|
int bonus;
|
|
if (vybrana_zbran>-1)
|
|
if (vybrana_zbran>0) bonus=p->bonus_zbrani[glob_items[vybrana_zbran-1].typ_zbrane];
|
|
else bonus=p->bonus_zbrani[TPW_OST];
|
|
else bonus=0;
|
|
return bonus;
|
|
}
|
|
|
|
static void pouzij_svitek(THUMAN *p,int ruka)
|
|
{
|
|
int it=p->wearing[ruka]-1;
|
|
short s[2];
|
|
|
|
thing_cast(glob_items[it].spell,p-postavy,p->sektor,NULL,0);
|
|
if (glob_items[it].magie==1)
|
|
{
|
|
s[0]=it+1;
|
|
s[1]=0;
|
|
destroy_items(s);
|
|
p->wearing[ruka]=0;
|
|
}
|
|
else
|
|
{
|
|
it=(p->wearing[ruka]=duplic_item(it+1));
|
|
it--;
|
|
glob_items[it].magie--;
|
|
}
|
|
}
|
|
|
|
static void play_weapon_anim(int anim_num,int hitpos)
|
|
{
|
|
char count_save=global_anim_counter;
|
|
int battlespeed=gamespeed-gamespeed*gamespeedbattle/5;
|
|
|
|
if (anim_num==0) return;
|
|
hold_timer(TM_SCENE,1);
|
|
if (battlespeed<1) battlespeed=1;
|
|
add_to_timer(TM_SCENE2,battlespeed,-1,hrat_souboj);
|
|
play_big_mgif_animation(anim_num+face_arr[4]);
|
|
do
|
|
{
|
|
while (global_anim_counter==count_save)
|
|
{
|
|
do_events();
|
|
}
|
|
count_save=global_anim_counter;
|
|
}
|
|
while (hitpos-- && running_anm);
|
|
delete_from_timer(TM_SCENE2);
|
|
hold_timer(TM_SCENE,0);
|
|
cancel_render=1;
|
|
}
|
|
|
|
void pouzij_zbran(THUMAN *p,int ruka)
|
|
{
|
|
int itm,where;
|
|
TITEM *it;
|
|
int bonus;
|
|
int wf=weigth_defect(p)+1;
|
|
|
|
|
|
p->kondice-=wf;
|
|
if (ruka==2) ruka=plr_switcher[p-postavy];
|
|
where=PO_RUKA_L+ruka;
|
|
itm=p->wearing[where];
|
|
SEND_LOG("(BATTLE) Player uses weapon %d.in %s hand",itm,where?"right":"left");
|
|
if (p->stare_vls[VLS_KOUZLA] & SPL_INVIS)
|
|
{
|
|
p->stare_vls[VLS_KOUZLA]&=~SPL_INVIS;
|
|
prepocitat_postavu(p);
|
|
build_all_players();
|
|
}
|
|
vybrana_zbran=itm;
|
|
bonus=vypocti_bonus(p,itm);
|
|
if (itm>0)
|
|
memcpy(&p->vlastnosti[VLS_MGSIL_L],&glob_items[itm-1].zmeny[VLS_MGSIL_L],3*sizeof(short));
|
|
else
|
|
memset(&p->vlastnosti[VLS_MGSIL_L],0,3*sizeof(short));
|
|
if (!itm || (it=&glob_items[itm-1])->druh==TYP_UTOC)
|
|
{
|
|
TMOB *m;int mm,chaos;
|
|
mm=vyber_potvoru(p->sektor,p->direction,&chaos);
|
|
if (mm>=0)
|
|
{
|
|
TITEM *it=glob_items+itm-1;
|
|
m=mobs+mm;
|
|
bott_draw(1);
|
|
anim_mirror=ruka==0;
|
|
prejdi_na_pohled(p);
|
|
if (itm) play_weapon_anim(it->weapon_attack,it->hitpos);
|
|
if (utok_na_sektor(p,m,chaos,bonus)>0 && itm && rnd(100)+1<it->magie)
|
|
thing_cast(it->spell,p-postavy,p->sektor,m,1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
prejdi_na_pohled(p);
|
|
switch(it->druh)
|
|
{
|
|
case TYP_VRHACI:hod_dykou(p,where,bonus);break;
|
|
case TYP_STRELNA:vystrel_sip(p,bonus);break;
|
|
case TYP_SVITEK:pouzij_svitek(p,where);break;
|
|
}
|
|
}
|
|
bott_draw(0);
|
|
}
|
|
|
|
static word last_sector;
|
|
static char valid_sectors(word sector)
|
|
{
|
|
int pp;
|
|
int i;
|
|
|
|
last_sector=sector;
|
|
if (mob_map[sector]) return 0; //nevyhovujici
|
|
pp=map_sectors[sector].sector_type;
|
|
if (pp==S_DIRA || ISTELEPORT(pp)) return 0;
|
|
for (i=0;i<4;i++) if (map_sectors[sector].step_next[i] && mob_map[map_sectors[sector].step_next[i]]) return 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
static char StrachPostavy(THUMAN *p)
|
|
{
|
|
word *cesta;
|
|
int i;
|
|
int ln;
|
|
int wf=weigth_defect(p)+1;
|
|
|
|
prejdi_na_pohled(p);
|
|
cur_group=p->groupnum;
|
|
for(select_player=0;select_player<6;select_player++) if (postavy+select_player==p) break;
|
|
bott_draw(0);
|
|
labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,valid_sectors,NULL);
|
|
ln=labyrinth_find_path(p->sektor,last_sector,SD_PLAY_IMPS,valid_sectors,&cesta);
|
|
if (cesta[0]==0) {free(cesta);return 0;}
|
|
for (i=0;i<6 && cesta[i] && p->kondice ;i++)
|
|
{
|
|
int dir;
|
|
for (dir=0;dir<4;dir++) if (map_sectors[p->sektor].step_next[dir]==cesta[i]) break;
|
|
destroy_player_map();
|
|
p->direction=dir;
|
|
p->sektor=cesta[i];
|
|
build_player_map();
|
|
prejdi_na_pohled(p);
|
|
Sleep(200);
|
|
p->kondice-=wf;
|
|
}
|
|
p->provadena_akce+=p->programovano-1;
|
|
p->programovano=1;
|
|
free(cesta);
|
|
return 1;
|
|
}
|
|
|
|
void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje
|
|
{
|
|
static char nowait=0;
|
|
unused;
|
|
|
|
if (msg->msg==E_IDLE && (!neco_v_pohybu || !battle || nowait)&& !norefresh && !cancel_render)
|
|
{
|
|
short nxt;
|
|
|
|
if (check_end_game()==1)
|
|
{
|
|
wire_end_game();
|
|
return;
|
|
}
|
|
vybrana_zbran=-1;
|
|
cancel_render=1;
|
|
nxt=*prave_hraje++;
|
|
anim_mirror=0;
|
|
if (nxt)
|
|
{
|
|
if (nxt>0)
|
|
{
|
|
nxt--;
|
|
SEND_LOG("(BATTLE) Mobile action (%d. %s)",nxt,mobs[nxt].name);
|
|
nowait=akce_moba_zac(&mobs[nxt]) && *prave_hraje>0;
|
|
neco_v_pohybu=1;
|
|
cislo_potvory=nxt;
|
|
}
|
|
else
|
|
if(nxt==-255)
|
|
{
|
|
int i;
|
|
SEND_LOG("(BATTLE) Ending round...",nxt,mobs[nxt].name);
|
|
delete_from_timer(TM_SCENE);
|
|
add_to_timer(TM_SCENE,gamespeed,-1,refresh_scene);
|
|
for(i=0;i<MAX_MOBS;i++)
|
|
if (~mobs[i].vlajky & MOB_IN_BATTLE)
|
|
{
|
|
mob_test_na_bitvu(mobs+i);
|
|
if (mobs[i].vlajky & MOB_LIVE && mobs[i].stay_strategy & 1)
|
|
{rozhodni_o_smeru(&mobs[i]);krok_moba(&mobs[i]);}
|
|
}
|
|
check_all_mobs_battle();
|
|
minwait=16;
|
|
maxwait=32;
|
|
neco_v_pohybu=1;
|
|
nowait=1;
|
|
}
|
|
else if (nxt<0)
|
|
{
|
|
THUMAN *p;
|
|
|
|
nowait=0;
|
|
nxt=abs(nxt)-1;
|
|
p=postavy+nxt;
|
|
select_player=nxt;
|
|
if (p->programovano && p->lives)
|
|
{
|
|
plr_switcher[select_player]=!plr_switcher[select_player];
|
|
cur_group=p->groupnum;
|
|
cancel_render=1;
|
|
if (p->kondice || p->provadena_akce->action==AC_STAND)
|
|
{
|
|
if (p->vlastnosti[VLS_KOUZLA] & SPL_FEAR && StrachPostavy(p))
|
|
{}
|
|
else
|
|
{
|
|
SEND_LOG("(BATTLE) Player Action '%s', number: %d",p->jmeno,p->provadena_akce->action);
|
|
switch(p->provadena_akce->action)
|
|
{
|
|
case AC_MOVE:
|
|
{
|
|
int wf=weigth_defect(p)+1;
|
|
p->actions++;
|
|
p->kondice-=p->actions*wf;
|
|
if (p->kondice<0)
|
|
{
|
|
p->actions+=p->kondice*wf;
|
|
p->kondice=0;
|
|
if (p->actions<0)
|
|
{
|
|
p->actions=0;
|
|
break;
|
|
}
|
|
}
|
|
viewsector=p->sektor;
|
|
viewdir=p->direction;
|
|
wire_presun_postavy();
|
|
break;
|
|
}
|
|
case AC_ATTACK:pouzij_zbran(p,p->provadena_akce->data1);break;
|
|
case AC_ARMOR:souboje_prezbrojeni(nxt);
|
|
bott_draw(1);
|
|
other_draw();
|
|
break;
|
|
case AC_THROW:
|
|
{
|
|
int x,y;
|
|
memcpy(&picked_item,&p->provadena_akce->data2,sizeof(short *));
|
|
x=p->provadena_akce->data1;
|
|
y=(x>>8)*2;x=(x & 0xff)*4;
|
|
prejdi_na_pohled(p);
|
|
throw_fly(x,y,0);
|
|
cislo_potvory=-2;
|
|
neco_v_pohybu=1;
|
|
}
|
|
case AC_STAND:pomala_regenerace_postavy(p);break;
|
|
case AC_RUN:utek_postavy(p);break;
|
|
case AC_MAGIC:
|
|
prejdi_na_pohled(p);
|
|
bott_draw(1);
|
|
teleport_target=p->provadena_akce->data2;
|
|
cast(p->provadena_akce->data1,p,select_player,0);
|
|
cislo_potvory=-2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
neco_v_pohybu=1;
|
|
p->provadena_akce++;
|
|
p->programovano--;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nowait=0;
|
|
konec_kola();
|
|
check_all_mobs_battle();
|
|
mouse_set_default(H_MS_DEFAULT);
|
|
if (battle)
|
|
{
|
|
delete_from_timer(TM_SCENE);
|
|
zacatek_kola();
|
|
unwire_proc();
|
|
wire_programming();
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
THUMAN *p;
|
|
|
|
SEND_LOG("(BATTLE) Leaving battle",0,0);
|
|
prekvapeni=0;
|
|
unwire_proc();
|
|
wire_main_functs();
|
|
bott_draw(1);
|
|
running_battle=0;
|
|
for(i=0;p=&postavy[i],i<POCET_POSTAV && (p->sektor!=viewsector || !p->used || !p->groupnum);i++);
|
|
if (i==POCET_POSTAV)
|
|
for(i=0;p=&postavy[i],i<POCET_POSTAV && (!p->used || !p->groupnum);i++);
|
|
cur_group=postavy[i].groupnum;
|
|
viewsector=postavy[i].sektor;
|
|
viewdir=postavy[i].direction;
|
|
build_player_map();
|
|
GlobEvent(MAGLOB_AFTERBATTLE,viewsector,viewdir);
|
|
}
|
|
msg->msg=-2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void wire_jadro_souboje()
|
|
{
|
|
int battlespeed=gamespeed-gamespeed*gamespeedbattle/5;
|
|
recalc_volumes(viewsector,viewdir);
|
|
if (battlespeed<1) battlespeed=1;
|
|
add_to_timer(TM_SCENE,battlespeed,-1,hrat_souboj);
|
|
send_message(E_ADD,E_IDLE,jadro_souboje);
|
|
mouse_set_default(H_MS_SOUBOJ);
|
|
unwire_proc=unwire_jadro_souboje;
|
|
cur_mode=MD_INBATTLE;
|
|
pgm_help=10;
|
|
}
|
|
|
|
void unwire_jadro_souboje()
|
|
{
|
|
delete_from_timer(TM_SCENE);
|
|
send_message(E_DONE,E_IDLE,jadro_souboje);
|
|
mouse_set_default(H_MS_DEFAULT);
|
|
wire_proc=wire_jadro_souboje;
|
|
pgm_help=0;
|
|
}
|
|
|
|
void fill_rune(char *d,int i)
|
|
{
|
|
int x,y;char *dd;
|
|
|
|
dd=((char *)d)+6+512;
|
|
for(y=378;y<480;y++)
|
|
{
|
|
word *z;
|
|
z=GetScreenAdr()+y*scr_linelen2;
|
|
for(x=520;x<640;x++)
|
|
if (*dd++==i) z[x]=z[x]-((z[x] & RGB555(28,28,28))>>2);
|
|
}
|
|
|
|
}
|
|
|
|
static void *runebar;
|
|
static char *rune_name=NULL;
|
|
|
|
void display_rune_bar()
|
|
{
|
|
short coords[][2]={{3,26},{32,26},{61,26},{90,26},{18,64},{47,64},{76,64}};
|
|
char c;
|
|
int i;
|
|
|
|
schovej_mysku();
|
|
if (runebar!=NULL) put_picture(520,378,runebar);
|
|
else
|
|
{
|
|
put_picture(520,378,ablock(H_RUNEBAR1+sel_zivel));
|
|
c=runes[sel_zivel];
|
|
for(i=0;i<7;i++,c>>=1)
|
|
if (!(c & 1)) put_picture(520+coords[i][0],378+coords[i][1],ablock(H_RUNEHOLE));
|
|
else if (!get_rune_enable(&postavy[select_player],(sel_zivel*7+i)*3)) fill_rune((char *)ablock(H_RUNEMASK),i+6);
|
|
if (sel_zivel) trans_bar(520,378,sel_zivel*24,22,0);
|
|
if (sel_zivel!=4)trans_bar(544+sel_zivel*24,378,96-sel_zivel*24,22,0);
|
|
runebar=getmem(120*102*2+6);
|
|
get_picture(520,378,120,102,runebar);
|
|
}
|
|
ukaz_mysku();
|
|
if (je_myska_zobrazena())showview(520,378,120,102);
|
|
}
|
|
|
|
|
|
|
|
void rune_bar_redrawing()
|
|
{
|
|
redraw_scene();
|
|
if (!norefresh && !cancel_render)
|
|
{
|
|
schovej_mysku();
|
|
program_draw();
|
|
display_rune_bar();
|
|
ukaz_mysku();
|
|
showview(0,0,0,0);
|
|
}
|
|
}
|
|
|
|
|
|
void display_power_bar(char drw)
|
|
{
|
|
int coords[][2]={{20,11},{20,41},{20,71}};
|
|
int i;
|
|
|
|
schovej_mysku();
|
|
put_picture(520,378,ablock(H_POWERBAR));
|
|
for(i=0;i<3;i++)
|
|
put_8bit_clipped(ablock(H_POWERLED),520+coords[i][0]+(378+coords[i][1])*scr_linelen2+GetScreenAdr(),24*powers[i],21,24);
|
|
ukaz_mysku();
|
|
if (drw) showview(520,378,120,102);
|
|
}
|
|
|
|
void display_power_bar_tm(THE_TIMER *tm)
|
|
{
|
|
tm;
|
|
display_power_bar(1);
|
|
}
|
|
|
|
void wire_select_rune();
|
|
void unwire_select_rune();
|
|
void wire_select_power();
|
|
|
|
char cancel_power(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
xa;ya;xr;yr;id;
|
|
schovej_mysku();
|
|
unwire_proc();
|
|
magic_data->action=0;
|
|
after_spell_wire();
|
|
mouse_set_default(H_MS_DEFAULT);
|
|
ukaz_mysku();
|
|
return 1;
|
|
}
|
|
|
|
char ask_who_proc(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
THUMAN *p;
|
|
int i;
|
|
word *xs;
|
|
|
|
xs=ablock(H_OKNO);
|
|
i=xr/xs[0];yr;xa;ya;id;
|
|
if (i<POCET_POSTAV)
|
|
{
|
|
char c;
|
|
i=group_sort[i];
|
|
p=&postavy[i];
|
|
c=p->sektor!=viewsector;
|
|
if (p->used)
|
|
if ((!far_play && !c || !death_play && c) && death_play==(p->lives==0))
|
|
{
|
|
if (get_spell_teleport(magic_data->data1))
|
|
if ((magic_data->data2=select_teleport_target())==0)
|
|
{
|
|
cancel_power(id,xa,ya,xr,yr);
|
|
return 1;
|
|
}
|
|
magic_data->data1+=(i+1)<<9;
|
|
magic_data->action=AC_MAGIC;
|
|
if (battle) souboje_vybrano(AC_MAGIC);
|
|
unwire_proc();
|
|
after_spell_wire();
|
|
mouse_set_default(H_MS_DEFAULT);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void vyber_cil(int typ)
|
|
{
|
|
death_play=(typ==3)?1:0;
|
|
far_play=(typ==4)?1:0;
|
|
change_click_map(clk_power,CLK_POWER_WHO);
|
|
mouse_set_default(H_MS_WHO);
|
|
}
|
|
|
|
char power(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
xa;ya;xr;yr;
|
|
if (powers[id]==1) return 1;
|
|
schovej_mysku();
|
|
display_power_bar(0);
|
|
trans_bar(520+44,378+11+30*id,76,24,RGB555(31,31,31));
|
|
mouse_set_default(H_MS_DEFAULT);
|
|
ukaz_mysku();
|
|
showview(520,378,120,102);
|
|
magic_data->data1-=magic_data->data1 % 3;
|
|
magic_data->data1+=id;
|
|
id=magic_data->data1;
|
|
if ((id=ask_who(id))>1)
|
|
{
|
|
vyber_cil(id);
|
|
return 1;
|
|
}
|
|
magic_data->action=AC_MAGIC;
|
|
if (get_spell_teleport(magic_data->data1))
|
|
if ((magic_data->data2=select_teleport_target())==0)
|
|
{
|
|
cancel_power(id,xa,ya,xr,yr);
|
|
return 1;
|
|
}
|
|
if (id==1) magic_data->data1+=(select_player+1)<<9;
|
|
schovej_mysku();
|
|
if (battle) souboje_vybrano(AC_MAGIC);
|
|
unwire_proc();
|
|
after_spell_wire();
|
|
ukaz_mysku();
|
|
return 1;
|
|
}
|
|
|
|
char runes_mask(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
char *c;
|
|
int cc;
|
|
short *d;
|
|
|
|
id;ya;xa;
|
|
d=ablock(H_RUNEMASK);
|
|
c=((char *)d)+6+512+xr+yr*d[0];
|
|
cc=*c-6;
|
|
if (*c)
|
|
if (*c<6 && ms_last_event.event_type & 0x2) sel_zivel=*c-1;
|
|
else if (runes[sel_zivel] & (1<<cc))
|
|
{
|
|
int x=(sel_zivel*7+(cc))*3;
|
|
if (ms_last_event.event_type & 0x2)
|
|
{
|
|
magic_data->data1=x;
|
|
unwire_select_rune();
|
|
wire_select_power();
|
|
schovej_mysku();
|
|
fill_rune((char *)d,*c);
|
|
ukaz_mysku();
|
|
showview(520,378,120,102);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
rune_name=get_rune_name(x);
|
|
}
|
|
}
|
|
if (cc<0) rune_name=NULL;
|
|
free(runebar);runebar=NULL;
|
|
display_rune_bar();
|
|
return 1;
|
|
}
|
|
|
|
char cancel_runes(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
xa;ya;xr;yr;id;
|
|
rune_name=NULL;
|
|
schovej_mysku();
|
|
unwire_select_rune();
|
|
magic_data->action=0;
|
|
after_spell_wire();
|
|
ukaz_mysku();
|
|
return 1;
|
|
}
|
|
|
|
void unwire_select_rune()
|
|
{
|
|
wire_proc=wire_select_rune;
|
|
delete_from_timer(TM_DELAIER);
|
|
delete_from_timer(TM_SCENE);
|
|
cancel_render=1;
|
|
free(runebar);runebar=NULL;
|
|
}
|
|
|
|
void wire_select_rune()
|
|
{
|
|
THUMAN *p;
|
|
HUM_ACTION *c;
|
|
|
|
mute_all_tracks(0);
|
|
p=&postavy[select_player];
|
|
c=p->zvolene_akce;while (c->action) c++;
|
|
magic_data=c;
|
|
c++;
|
|
c->action=0;
|
|
unwire_proc();
|
|
change_click_map(clk_runes,CLK_RUNES);
|
|
add_to_timer(TM_DELAIER,12,1,display_rune_bar);
|
|
add_to_timer(TM_SCENE,gamespeed,-1,rune_bar_redrawing);
|
|
unwire_proc=unwire_select_rune;
|
|
cancel_render=1;
|
|
}
|
|
|
|
void wire_select_rune_fly()
|
|
{
|
|
mute_all_tracks(0);
|
|
unwire_proc();
|
|
change_click_map(clk_runes,CLK_RUNES);
|
|
add_to_timer(TM_DELAIER,12,1,display_rune_bar);
|
|
add_to_timer(TM_SCENE,gamespeed,-1,rune_bar_redrawing);
|
|
unwire_proc=unwire_select_rune;
|
|
cancel_render=1;
|
|
}
|
|
|
|
void unwire_select_power()
|
|
{
|
|
rune_name=NULL;
|
|
delete_from_timer(TM_DELAIER);
|
|
}
|
|
|
|
void wire_select_power()
|
|
{
|
|
THUMAN *p;
|
|
int i;
|
|
|
|
p=&postavy[select_player];
|
|
mute_all_tracks(0);
|
|
unwire_proc();
|
|
for(i=0;i<3;i++) powers[i]=get_spell_color(p,magic_data->data1+i);
|
|
change_click_map(clk_power,CLK_POWER);
|
|
unwire_proc=unwire_select_power;
|
|
add_to_timer(TM_DELAIER,12,1,display_power_bar_tm);
|
|
}
|
|
|
|
|
|
|
|
void program_draw()
|
|
{
|
|
int x=54+74/2;
|
|
int i,j,maxy=0;
|
|
|
|
maxy;
|
|
schovej_mysku();
|
|
for(j=0;j<POCET_POSTAV;j++)
|
|
if (postavy[i=group_sort[j]].used)
|
|
{
|
|
int y;
|
|
|
|
y=postavy[i].programovano*10;
|
|
if (y>maxy) maxy=y;
|
|
}
|
|
if (!maxy && (pgm_help || rune_name!=NULL)) maxy+=10;
|
|
if (maxy)
|
|
{
|
|
maxy+=5;
|
|
trans_bar(0,377-maxy,640,maxy,0);
|
|
}
|
|
for(j=0;j<POCET_POSTAV;j++)
|
|
if (postavy[i=group_sort[j]].used)
|
|
{
|
|
HUM_ACTION *c;
|
|
int y,j;
|
|
c=postavy[i].provadena_akce;
|
|
if (c==NULL) continue;
|
|
y=386-10*postavy[i].programovano;
|
|
set_font(H_FLITT5,PRG_COLOR);
|
|
for(j=0;j<postavy[i].programovano;j++)
|
|
{
|
|
set_aligned_position(x,y,1,2,texty[c->action+40]);
|
|
outtext(texty[c->action+40]);
|
|
c++;
|
|
y+=+10;
|
|
}
|
|
x+=74;
|
|
}
|
|
if(pgm_help || rune_name!=NULL)
|
|
{
|
|
char *c;
|
|
|
|
if (rune_name!=NULL) c=rune_name;else c=texty[40+pgm_help];
|
|
set_font(H_FLITT5,PRG_HELP_COLOR);
|
|
set_aligned_position(580,376,1,2,c);
|
|
outtext(c);
|
|
}
|
|
ukaz_mysku();
|
|
}
|
|
|
|
|
|
void souboje_redrawing()
|
|
{
|
|
if (neco_v_pohybu) calc_mobs();
|
|
calc_animations();
|
|
redraw_scene();
|
|
if (!norefresh && !cancel_render)
|
|
{
|
|
schovej_mysku();
|
|
program_draw();
|
|
ukaz_mysku();
|
|
showview(0,0,0,0);
|
|
}
|
|
}
|
|
|
|
|
|
void souboje_stisknout(int d)
|
|
{
|
|
update_mysky();
|
|
schovej_mysku();
|
|
d--;
|
|
d*=105;
|
|
put_8bit_clipped(ablock(H_BATTLE_CLICK),378*scr_linelen2+520+GetScreenAdr(),d,120,102);
|
|
ukaz_mysku();
|
|
showview(520,378,120,102);
|
|
cancel_render=1;
|
|
}
|
|
|
|
static void souboje_dalsi()
|
|
{
|
|
int i,j=12,cd;
|
|
for(i=0;group_sort[i]!=select_player;i++);
|
|
cd=postavy[select_player].groupnum;
|
|
do
|
|
{
|
|
i++;
|
|
if (i>=POCET_POSTAV) i=0;
|
|
select_player=group_sort[i];
|
|
j--;
|
|
}
|
|
while ((!postavy[select_player].used || !postavy[select_player].actions || (postavy[select_player].groupnum!=cd && j>6)) && j);
|
|
viewsector=postavy[select_player].sektor;
|
|
viewdir=postavy[select_player].direction;
|
|
}
|
|
|
|
void souboje_vybrano(int d)
|
|
{
|
|
if (d==AC_STAND || d==AC_RUN) postavy[select_player].actions=0;
|
|
else postavy[select_player].actions--;
|
|
postavy[select_player].programovano++;
|
|
if (!postavy[select_player].actions)
|
|
souboje_dalsi();
|
|
bott_draw(1);
|
|
}
|
|
|
|
void zrusit_akce()
|
|
{
|
|
HUM_ACTION *c;
|
|
|
|
c=postavy[select_player].zvolene_akce;
|
|
while (c->action)
|
|
if (c->action==AC_THROW)
|
|
{
|
|
poloz_vsechny_predmety();
|
|
memcpy(&picked_item,&c->data2,sizeof(short *));
|
|
c++;
|
|
}
|
|
else c++;
|
|
postavy[select_player].zvolene_akce->action=0;
|
|
postavy[select_player].actions=get_ap(postavy[select_player].vlastnosti);;
|
|
postavy[select_player].programovano=0;
|
|
postavy[select_player].utek=0;
|
|
pick_set_cursor();
|
|
bott_draw(1);
|
|
}
|
|
|
|
char souboje_clk_throw(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
HUM_ACTION *c;
|
|
|
|
if (postavy[select_player].actions==0) return 0;
|
|
if (picked_item==NULL) return 0;
|
|
postavy[select_player].direction=viewdir;
|
|
c=postavy[select_player].zvolene_akce;while (c->action) c++;
|
|
c->action=AC_THROW;
|
|
memcpy(&c->data2,&picked_item,sizeof(short *));picked_item=NULL;
|
|
c->data1=xa/4+(ya/2)*256;
|
|
c++;
|
|
c->action=0;
|
|
pick_set_cursor();id;xr;yr;
|
|
souboje_vybrano(AC_THROW);
|
|
return 1;
|
|
}
|
|
|
|
|
|
char mask_click_help(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
char *c;
|
|
int d;
|
|
word *mask;
|
|
|
|
id;xa;ya;
|
|
mask=(word *)ablock(H_BATTLE_MASK);
|
|
c=(char *)mask+6+512;
|
|
c+=yr*mask[0]+xr;
|
|
d=*c;
|
|
if (d) pgm_help=d;
|
|
return 1;
|
|
}
|
|
|
|
char mask_click_help_clear(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
id;xa;ya;
|
|
xr;yr;
|
|
pgm_help=0;
|
|
return 1;
|
|
}
|
|
|
|
static void zahajit_kolo(char prekvapeni)
|
|
{
|
|
int i,j;
|
|
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
{
|
|
THUMAN *p=&postavy[i];
|
|
int sect=p->sektor,dir=p->direction;
|
|
char monster=0;
|
|
char monster_far=0;
|
|
char lnear=1;
|
|
int counter=5;
|
|
short w1,w2,dw1,dw2,w;
|
|
|
|
while (~map_sides[(sect<<2)+dir].flags & SD_PLAY_IMPS)
|
|
{
|
|
int m1,m2;
|
|
sect=map_sectors[sect].step_next[dir];
|
|
if (numplayers(sect,0)>2) break;
|
|
m1=mob_map[sect]-1;if (m1>=0) m2=mobs[m1].next-1;else m2=-1;
|
|
if ((m1>=0 && mobs[m1].vlajky & MOB_IN_BATTLE) || (m2>=0 && mobs[m2].vlajky & MOB_IN_BATTLE))
|
|
if (lnear) monster=1;else monster_far=1;
|
|
lnear=0;counter--;if(!counter) break;
|
|
}
|
|
w1=p->wearing[PO_RUKA_L];w2=p->wearing[PO_RUKA_R];
|
|
if (w1) dw1=glob_items[w1-1].druh;else dw1=-1;
|
|
if (w2) dw2=glob_items[w2-1].druh;else dw2=-1;
|
|
w=0;
|
|
if (dw1==TYP_STRELNA && p->sipy || dw1==TYP_VRHACI) w|=1;
|
|
if (dw2==TYP_STRELNA && p->sipy || dw2==TYP_VRHACI) w|=2;
|
|
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 (prekvapeni || !p->actions || !autoattack || !monster)
|
|
{
|
|
p->programovano++;p->zvolene_akce->action=AC_STAND;
|
|
}
|
|
else
|
|
{
|
|
for(j=0;j<p->actions;j++)
|
|
{
|
|
p->zvolene_akce[j].action=AC_ATTACK;
|
|
p->zvolene_akce[j].data1=w;
|
|
}
|
|
p->programovano=(char)p->actions;
|
|
}
|
|
}
|
|
rozhodni_o_poradi();
|
|
unwire_proc();
|
|
wire_jadro_souboje();
|
|
send_message(E_KOUZLO_KOLO);
|
|
}
|
|
|
|
char mask_click(int id,int xa,int ya,int xr,int yr)
|
|
{
|
|
char *c;
|
|
int d;
|
|
word *mask;
|
|
|
|
id;xa;ya;
|
|
mask=(word *)ablock(H_BATTLE_MASK);
|
|
c=(char *)mask+6+512;
|
|
c+=yr*mask[0]+xr;
|
|
d=*c;
|
|
if (d)
|
|
{
|
|
souboje_stisknout(d);
|
|
switch(d)
|
|
{
|
|
case AC_RUN: postavy[select_player].utek=5+postavy[select_player].actions;
|
|
case AC_ATTACK:
|
|
case AC_STAND:
|
|
case AC_ARMOR:
|
|
case AC_MOVE:
|
|
case AC_MAGIC:if (postavy[select_player].actions)
|
|
{
|
|
HUM_ACTION *c;
|
|
postavy[select_player].direction=viewdir;
|
|
c=postavy[select_player].zvolene_akce;while (c->action) c++;
|
|
if (d==AC_MAGIC)
|
|
{
|
|
wire_select_rune();
|
|
return 1;
|
|
}
|
|
c->action=d;
|
|
if (d==AC_ATTACK) c->data1=select_weapon(&postavy[select_player],1);
|
|
c++;
|
|
c->action=0;
|
|
souboje_vybrano(d);
|
|
}
|
|
break;
|
|
case AC_CANCEL:zrusit_akce();break;
|
|
case AC_START:zahajit_kolo(0);
|
|
souboje_stisknout(d);
|
|
return 0;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
bott_draw(1);
|
|
return 1;
|
|
}
|
|
void fix_group_direction()
|
|
{
|
|
int i,g;
|
|
|
|
g=postavy[select_player].groupnum;
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
if (postavy[i].used && postavy[i].groupnum==g && !postavy[i].programovano) postavy[i].direction=viewdir;
|
|
}
|
|
|
|
void souboje_turn(char smer)
|
|
{
|
|
if (pass_zavora) return;
|
|
norefresh=1;
|
|
hold_timer(TM_BACK_MUSIC,1);
|
|
viewdir=(viewdir+smer)&3;
|
|
if (GetKeyState(VK_SHIFT) & 0x80) fix_group_direction();
|
|
else postavy[select_player].direction=viewdir;
|
|
render_scene(viewsector,viewdir);
|
|
hide_ms_at(387);
|
|
if (smer==1) turn_left();
|
|
else turn_right();
|
|
OutBuffer2nd();
|
|
bott_draw(0);
|
|
other_draw();
|
|
program_draw();
|
|
draw_medium_map();
|
|
ukaz_mysku();
|
|
showview(0,0,0,0);
|
|
schovej_mysku();
|
|
CopyBuffer2nd();
|
|
ukaz_mysku();
|
|
norefresh=0;
|
|
cancel_render=1;
|
|
hold_timer(TM_BACK_MUSIC,0);
|
|
recalc_volumes(viewsector,viewdir);
|
|
mix_back_sound(0);
|
|
}
|
|
|
|
|
|
|
|
void programming_keyboard(EVENT_MSG *msg,void **unused)
|
|
{
|
|
char c;
|
|
|
|
unused;
|
|
if (msg->msg==E_KEYBOARD)
|
|
{
|
|
c=(*(int *)msg->data)>>8;
|
|
while (_bios_keybrd(_KEYBRD_READY) ) _bios_keybrd(_KEYBRD_READ);
|
|
switch (c)
|
|
{
|
|
case 1:konec(0,0,0,0,0);break;
|
|
case 'M':souboje_turn(1);break;
|
|
case 'K':souboje_turn(-1);break;
|
|
case '=':unwire_proc();cancel_render=1;wire_save_load(0);break;
|
|
case '>':game_setup(0,0,0,0,0);break;
|
|
case 57:souboje_dalsi();bott_draw(1);break;
|
|
case 15:
|
|
case 50:
|
|
if (GlobEvent(MAGLOB_BEFOREMAPOPEN,viewsector,viewdir))
|
|
show_automap(1);
|
|
break;
|
|
case 0x17:unwire_proc();
|
|
wire_inv_mode(human_selected);
|
|
case 82:group_all();break;
|
|
CASE_KEY_1_6:c=group_sort[c-2];
|
|
if (postavy[c].used)
|
|
{
|
|
select_player=c;
|
|
zmen_skupinu(postavy+c);
|
|
bott_draw(1);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void unwire_programming()
|
|
{
|
|
disable_click_map();
|
|
send_message(E_DONE,E_KEYBOARD,programming_keyboard);
|
|
delete_from_timer(TM_SCENE);
|
|
cancel_render=1;
|
|
wire_proc=wire_programming;
|
|
}
|
|
|
|
|
|
|
|
void wire_programming()
|
|
{
|
|
schovej_mysku();
|
|
after_spell_wire=wire_programming;
|
|
cur_mode=MD_INBATTLE;
|
|
battle_mode=0;
|
|
change_click_map(clk_souboje,CLK_SOUBOJE);
|
|
send_message(E_ADD,E_KEYBOARD,programming_keyboard);
|
|
add_to_timer(TM_SCENE,gamespeed,-1,souboje_redrawing);
|
|
ukaz_mysku();
|
|
unwire_proc=unwire_programming;
|
|
bott_draw(1);
|
|
showview(0,0,0,0);
|
|
recalc_volumes(viewsector,viewdir);
|
|
if (autostart_round) zahajit_kolo(1);
|
|
}
|
|
|
|
void wait_to_stop(EVENT_MSG *msg,void **unused)
|
|
{
|
|
|
|
unused;
|
|
if (msg->msg==E_IDLE)
|
|
if (!neco_v_pohybu)
|
|
{
|
|
unwire_proc();
|
|
calc_mobs();
|
|
mouse_set_default(H_MS_DEFAULT);
|
|
refresh_scene();
|
|
cancel_render=1;
|
|
if (prekvapeni) zahajit_kolo(1);else wire_programming();
|
|
msg->msg=-2;
|
|
}
|
|
}
|
|
|
|
|
|
void start_battle()
|
|
{
|
|
spell_cast=0;
|
|
if (check_end_game())
|
|
{
|
|
wire_end_game();
|
|
return;
|
|
}
|
|
if (!GlobEvent(MAGLOB_BEFOREBATTLE,viewsector,viewdir))
|
|
{
|
|
int i;
|
|
battle=0;
|
|
for (i=0;i<MAX_MOBS;i++) mobs[i].vlajky &= ~MOB_IN_BATTLE;
|
|
return;
|
|
}
|
|
neco_v_pohybu=1;
|
|
cur_mode=MD_INBATTLE;
|
|
send_message(E_DONE,E_KEYBOARD,game_keyboard);
|
|
disable_click_map();
|
|
if (!running_battle)
|
|
{
|
|
SEND_LOG("(BATTLE) Battle started (monster: %s)",attack_mob!=NULL?attack_mob->name:"(NULL)",0);
|
|
poloz_vsechny_predmety();
|
|
zacatek_kola();
|
|
running_battle=1;
|
|
// select_player=att_player;
|
|
cislo_kola=0;
|
|
if (prekvapeni)
|
|
{
|
|
unwire_proc();
|
|
mouse_set_default(H_MS_SOUBOJ);
|
|
zahajit_kolo(1);
|
|
}
|
|
else
|
|
{
|
|
unwire_proc();
|
|
wire_programming();
|
|
}
|
|
}
|
|
}
|
|
|
|
int pocet_zivych(int sector)
|
|
{
|
|
char z=0;
|
|
int i;
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
{
|
|
THUMAN *p=&postavy[i];
|
|
|
|
if (p->used && p->lives && p->sektor==sector) z++;
|
|
}
|
|
return z;
|
|
}
|
|
|
|
void manashield_check(short *vls,short *lives,short *mana,int dostal)
|
|
{
|
|
if (vls[VLS_KOUZLA] & SPL_MANASHIELD)
|
|
{
|
|
*mana-=*mana>dostal?dostal:*mana;
|
|
if (!*mana) vls[VLS_KOUZLA]&=~SPL_MANASHIELD;
|
|
}
|
|
else
|
|
*lives-=dostal;
|
|
}
|
|
|
|
|
|
|
|
char zasah_veci(int sector,TFLY *fl)
|
|
{
|
|
int mob1,mob2;
|
|
TMOB *m1,*m2;
|
|
TITEM *it;
|
|
|
|
m1=NULL;
|
|
m2=NULL;
|
|
if (fl->items==NULL && fl->item==0) return 0;
|
|
if (fl->items==NULL) it=glob_items+fl->item-1;else it=&glob_items[*(fl->items)-1];
|
|
if (fl->flags & FLY_DESTROY_SEQ || !fl->speed) return 0;
|
|
if (fl->flags & FLY_DESTROY)
|
|
{
|
|
if (mob_map[sector] && fl->owner>=0)
|
|
{
|
|
if (fl->owner>=0) select_player=fl->owner-1;
|
|
if (it->druh!=TYP_VRHACI) return 1;
|
|
if (it->magie) area_cast(it->spell,sector,fl->owner,1);
|
|
mob1=mob_map[sector]-MOB_START;m1=&mobs[mob1];
|
|
mob2=m1->next-MOB_START;
|
|
if (mob2>=0)
|
|
{
|
|
m2=&mobs[mob2];
|
|
if (m2->vlajky & MOB_PASSABLE) m2=NULL;//pruchozi nestvury nemaji affekt na hozenou vec
|
|
}
|
|
else m2=NULL;
|
|
if (m1->vlajky & MOB_PASSABLE) if (m2!=NULL) m1=m2;else return 0;
|
|
if (m2==NULL)
|
|
{
|
|
mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,1,fl->damage,fl->hit_bonus));
|
|
m1->dir=fl->smer+2&3;
|
|
}
|
|
else
|
|
{
|
|
mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,2,fl->damage,fl->hit_bonus));
|
|
mob_hit(m2,vypocet_zasahu(it->zmeny,m1->vlastnosti,2,fl->damage,fl->hit_bonus));
|
|
m1->dir=fl->smer+2&3;
|
|
m2->dir=fl->smer+2&3;
|
|
}
|
|
return 1;
|
|
}
|
|
else if (map_coord[sector].flags & MC_PLAYER && (fl->owner<=0 || pocet_zivych(sector)>2))
|
|
{
|
|
int kolik,i,c=0;
|
|
int owner=fl->owner;
|
|
|
|
if (it->druh!=TYP_VRHACI) return 1;
|
|
if (it->magie) area_cast(it->spell,sector,fl->owner,1);
|
|
for(i=0,kolik=0;i<POCET_POSTAV;kolik+=(postavy[i].sektor==sector?1:0),i++);
|
|
for(i=0;i<POCET_POSTAV;i++)
|
|
{
|
|
THUMAN *p=&postavy[i];
|
|
if (sector==p->sektor && p->lives && p->used)
|
|
{
|
|
char death;
|
|
short vlastnosti[VLS_MAX];
|
|
memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti));
|
|
if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti);
|
|
death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus),1);
|
|
if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva
|
|
c=1;
|
|
}
|
|
bott_draw(1);
|
|
}
|
|
return c;
|
|
}
|
|
}
|
|
else
|
|
if (mob_map[sector] && fl->owner>=0)
|
|
{
|
|
if (fl->owner>=0) select_player=fl->owner-1;
|
|
if (it->druh!=TYP_VRHACI) return 1;
|
|
mob1=mob_map[sector]-MOB_START;m1=&mobs[mob1];
|
|
mob2=m1->next-MOB_START;
|
|
if (mob2>=0)
|
|
{
|
|
int x1,y1;
|
|
m2=&mobs[mob2];
|
|
switch (fl->smer)
|
|
{
|
|
case 0:x1=fl->ypos;y1=32;break;
|
|
case 1:x1=-32;y1=fl->ypos;break;
|
|
case 2:x1=-fl->ypos;y1=-32;break;
|
|
case 3:x1=32;y1=-fl->ypos;break;
|
|
}
|
|
if (abs(x1-m1->locx+128)+abs(y1-m1->locy+128)>abs(x1-m2->locx+128)+abs(y1-m2->locy+128)) m1=m2;
|
|
}
|
|
if (m1->vlajky & MOB_PASSABLE) return 0;
|
|
mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,(m2!=NULL)+1,fl->damage,fl->hit_bonus));
|
|
if (it->druh==TYP_VRHACI) fl->flags|=FLY_DESTROY;
|
|
if (it->umisteni!=PL_SIP && !(it->flags & ITF_DESTROY))
|
|
{
|
|
int i;
|
|
for(i=0;i<MOBS_INV;i++) if (m1->inv[i]==0) { m1->inv[i]=it-glob_items+1;break;}
|
|
if (i==MOBS_INV) fl->flags &=FLY_DESTROY;
|
|
}
|
|
m1->dir=fl->smer+2&3;
|
|
return 1;
|
|
}
|
|
else if (map_coord[sector].flags & MC_PLAYER && (fl->owner<=0 || pocet_zivych(sector)>2))
|
|
{
|
|
int kolik,i,j,c=0,r;
|
|
int owner=fl->owner;
|
|
|
|
if (it->druh!=TYP_VRHACI) return 1;else fl->flags|=FLY_DESTROY;
|
|
fl->speed=0;
|
|
for(i=0,kolik=0;i<POCET_POSTAV;kolik+=((postavy[i].sektor==sector && postavy[i].lives)?1:0),i++);
|
|
if (kolik) r=rnd(kolik)+1;else r=0;
|
|
for(i=0,j=0;i<r;i+=((postavy[j].sektor==sector && postavy[j].lives)?1:0),j++);
|
|
j--;
|
|
{
|
|
THUMAN *p=&postavy[j];
|
|
{
|
|
char death;
|
|
short vlastnosti[VLS_MAX];
|
|
memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti));
|
|
if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti);else uprav_podle_kondice(p,&kolik);
|
|
death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus),1);
|
|
if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva
|
|
c=1;
|
|
}
|
|
bott_draw(1);
|
|
}
|
|
return c;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void cast_wait(EVENT_MSG *msg,void **unused)
|
|
{
|
|
unused;
|
|
|
|
if (msg->msg==E_TIMER)
|
|
if (!neco_v_pohybu)
|
|
{
|
|
send_message(E_DONE,E_TIMER,cast_wait);
|
|
delete_from_timer(TM_SCENE);
|
|
wire_main_functs();
|
|
}
|
|
}
|
|
|
|
void wire_cast_spell()
|
|
{
|
|
if (spell_string.action)
|
|
{
|
|
teleport_target=spell_string.data2;
|
|
select_player=caster;
|
|
cast(spell_string.data1,&postavy[caster],caster,0);
|
|
/*add_to_timer(TM_SCENE,gamespeed,-1,hrat_souboj);
|
|
neco_v_pohybu=1;
|
|
send_message(E_ADD,E_TIMER,cast_wait);*/
|
|
}
|
|
wire_main_functs();
|
|
bott_draw(0);
|
|
}
|
|
|
|
void wire_fly_casting(int i)
|
|
{
|
|
if (!postavy[i].used || !postavy[i].lives) return;
|
|
magic_data=&spell_string;
|
|
memset(&spell_string,0,sizeof(spell_string));
|
|
after_spell_wire=wire_cast_spell;
|
|
select_player=i;
|
|
wire_select_rune_fly();
|
|
select_player=caster=i;
|
|
}
|
|
|
|
static void rozdelit_skryte_bonusy(THUMAN *hu)
|
|
{
|
|
short *vls,*vls2;
|
|
short p[]={VLS_SILA,VLS_SMAGIE,VLS_OBRAT};
|
|
short h[3];
|
|
register i;
|
|
|
|
vls=hu->vlastnosti;
|
|
vls2=hu->stare_vls;
|
|
if (vls[p[0]]<vls[p[1]]) {p[1]^=p[0];p[0]^=p[1];p[1]^=p[0];}
|
|
if (vls[p[1]]<vls[p[2]]) {p[2]^=p[1];p[1]^=p[2];p[2]^=p[1];}
|
|
if (vls[p[0]]<vls[p[1]]) {p[1]^=p[0];p[0]^=p[1];p[1]^=p[0];}
|
|
h[0]=rnd(5)+1;h[1]=rnd(3)+1;h[2]=1;
|
|
for(i=0;i<3;i++)
|
|
{
|
|
switch (p[i])
|
|
{
|
|
case VLS_SILA: vls2[VLS_MAXHIT]+=h[i];hu->lives+=h[i];break;
|
|
case VLS_SMAGIE: if (vls2[VLS_SMAGIE]) {vls2[VLS_MAXMANA]+=h[i];hu->mana+=h[i];}break;
|
|
case VLS_OBRAT: vls2[VLS_KONDIC]+=h[i];hu->kondice+=h[i];break;
|
|
}
|
|
}
|
|
prepocitat_postavu(hu);
|
|
}
|
|
|
|
|
|
void check_player_new_level(THUMAN *p)
|
|
{
|
|
int u;
|
|
|
|
u=p->level-1;
|
|
while (level_map[u]<=p->exp)
|
|
{
|
|
u++;p->bonus+=5;
|
|
rozdelit_skryte_bonusy(p);
|
|
prepocitat_postavu(p);
|
|
SEND_LOG("(GAME) Character '%s' raised a level %d",p->jmeno,u);
|
|
}
|
|
p->level=u+1;
|
|
}
|
|
|
|
|
|
void send_experience(TMOB *p,int dostal)
|
|
{
|
|
if (select_player<0) return;
|
|
if (isdemon(postavy+select_player)) return;
|
|
if (p->lives<=0)
|
|
{
|
|
int i;
|
|
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].lives)
|
|
{
|
|
postavy[i].exp+=p->bonus;
|
|
check_player_new_level(postavy+i);
|
|
}
|
|
if (hlubina_level==1)
|
|
{
|
|
postavy[select_player].lives=0;
|
|
player_check_death(postavy+select_player,0);
|
|
}
|
|
}
|
|
if (dostal>0) postavy[select_player].exp+=(long)((float)p->experience*(float)dostal/p->vlastnosti[VLS_MAXHIT]);
|
|
check_player_new_level(&postavy[select_player]);
|
|
}
|
|
|
|
|
|
void send_weapon_skill(int druh)
|
|
{
|
|
THUMAN *p=&postavy[select_player];
|
|
|
|
if (isdemon(p)) return;
|
|
if (p->bonus_zbrani[druh]<MAX_WEAPON_SKILL)
|
|
{
|
|
short *c=&p->bonus_zbrani[druh];
|
|
if (c[0]<MAX_WEAPON_SKILL-1)
|
|
{
|
|
p->weapon_expy[druh]++;
|
|
if (p->weapon_expy[druh]>=weapon_skill[c[0]])
|
|
{
|
|
c[0]++;
|
|
SEND_LOG("(GAME) Character '%s' raised new weaponskill in '%s'",p->jmeno,texty[91+druh]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
char player_check_death(THUMAN *p, char afterround)
|
|
{
|
|
p->used&=~0x80;
|
|
if (p->lives<=0 && p->groupnum)
|
|
if (!battle || afterround)
|
|
{
|
|
int mp;
|
|
int i;
|
|
if (isdemon(p))
|
|
{
|
|
unaffect_demon(p-postavy);
|
|
return 0;
|
|
}
|
|
for(i=0;i<HUMAN_PLACES;i++)
|
|
{
|
|
int j=p->wearing[i];
|
|
if (j)
|
|
{
|
|
short it[2];
|
|
it[1]=0;it[0]=j;j--;
|
|
if (glob_items[j].flags & ITF_NOREMOVE)
|
|
{
|
|
destroy_items(it);
|
|
p->wearing[i]=0;
|
|
}
|
|
}
|
|
}
|
|
p->groupnum=0;
|
|
p->lives=0;
|
|
if (p->level>1) p->exp=level_map[p->level-2];
|
|
p->kondice=0;
|
|
p->mana=0;
|
|
SEND_LOG("(GAME) Character '%s' died. R.I.P.",p->jmeno,0);
|
|
if (numplayers(p->sektor,0)==0) map_coord[p->sektor].flags &=~MC_PLAYER;
|
|
mp=map_sectors[p->sektor].sector_type;
|
|
if (mp==S_VODA || mp==S_LAVA || mp==S_VIR) p->sektor=0;
|
|
else map_coord[p->sektor].flags |= MC_DEAD_PLR;
|
|
GlobEvent(MAGLOB_ONDEADMAN+p->female,viewsector,viewdir);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if (p->lives<0) p->lives=0;
|
|
p->used|=0x80;
|
|
}
|
|
if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT];
|
|
return 0;
|
|
}
|
|
|
|
char mute_hit_sound=0;
|
|
|
|
char player_hit(THUMAN *p,int zraneni,char manashield)
|
|
{
|
|
char check=0;
|
|
|
|
if (!p->lives) return check;
|
|
if (zraneni>0)
|
|
{
|
|
THE_TIMER *tt;int h;
|
|
|
|
if (zraneni>p->lives) zraneni=p->lives;
|
|
p->dostal=zraneni;
|
|
if (manashield) manashield_check(p->vlastnosti,&p->lives,&p->mana,p->dostal); //manashield pro hrace
|
|
else p->lives-=zraneni;
|
|
if (p->female) h=H_SND_HEK1F;else h=H_SND_HEK1M;
|
|
h+=rnd(2);
|
|
if (!mute_hit_sound)
|
|
{
|
|
if (GlobEvent(MAGLOB_ONHITMAN+p->female,p->sektor,p->direction))
|
|
play_sample_at_sector(h,p->sektor,viewsector,0,0);
|
|
tt=add_to_timer(TM_CLEAR_ZASAHY,100+rnd(100),1,vymaz_zasahy);tt->userdata[0]=p-postavy;tt->userdata[1]=p->dostal;
|
|
}
|
|
mute_hit_sound=0;
|
|
if (immortality) p->lives=p->vlastnosti[VLS_MAXHIT];
|
|
check=player_check_death(p,0);
|
|
}
|
|
else
|
|
{
|
|
p->lives-=zraneni;
|
|
if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT];
|
|
}
|
|
return check;
|
|
}
|
|
|
|
void enforce_start_battle()
|
|
{
|
|
if (!battle && see_monster)
|
|
{
|
|
int i;THUMAN *h;
|
|
stop_all_mobs();battle=1;
|
|
for(i=0,h=postavy;i<POCET_POSTAV && (!h->used || !h->lives || h->groupnum!=cur_group);i++,h++);
|
|
if (i>=POCET_POSTAV) h=postavy,i=0;
|
|
att_player=i;
|
|
}
|
|
}
|
|
|
|
void uprav_podle_kondice(THUMAN *p,int *chaos)
|
|
{
|
|
if (p->kondice<(p->vlastnosti[VLS_POHYB]/2) || p->vlastnosti[VLS_POHYB]<4)
|
|
{
|
|
*chaos=999;
|
|
}
|
|
else
|
|
p->kondice--;
|
|
}
|
|
|
|
|
|
void correct_level()
|
|
{
|
|
THUMAN *h;
|
|
int i;
|
|
|
|
puts("\x7");
|
|
h=postavy;
|
|
for (i=0;i<POCET_POSTAV;i++)
|
|
if (h->used)
|
|
{
|
|
int j;
|
|
if (h->level>37 || (h->level>1 && h->exp<level_map[h->level-2]))
|
|
{
|
|
poloz_vsechny_predmety();
|
|
picked_item=NewArr(short,2);
|
|
picked_item[0]=h->level;
|
|
picked_item[1]=0;
|
|
pick_set_cursor();
|
|
}
|
|
h->level=1;
|
|
for (j=0;;j++) if (h->exp>level_map[j]) h->level=j+2;else break;
|
|
}
|
|
}
|