diff --git a/game/builder.c b/game/builder.c index cc884ee..470068d 100644 --- a/game/builder.c +++ b/game/builder.c @@ -89,17 +89,8 @@ word minimap[VIEW3D_Z+1][VIEW3D_X*2+1]; -//debug - !!!! +char log_combat=0; -int dhit=0; -int ddef=0; -int ddostal=0; -int dlives=0; -int dmzhit=0; -int dsee=0; -char show_debug=0; -char *debug_text; -char marker=0; SPECTXT_ARR spectxtr; @@ -1275,35 +1266,6 @@ void render_scene(int sector, int smer) if (lodka) zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ); } -void debug_print() - { - char s[256]; - static char indx=50; - static int counter=0; - - sprintf(s,"battle: %d waiting: %d lhit: %3d ldef: %3d hit: %3d magic-hit: %3d lives: %3d weapon: %d", - battle, neco_v_pohybu, dhit, ddef, ddostal, dmzhit, dlives, vybrana_zbran ); - trans_bar(0,17,640,15,0); - position(0,17);set_font(H_FONT6,0x3ff); - if (debug_text!=NULL) - { - outtext(debug_text); - counter++; - if (counter==100) - { - counter=0; - debug_text=NULL; - } - } - else outtext(s); - if (dsee) indx--; - if (!indx) - { - dsee=0; - indx=10; - } - - } void death_screen() { trans_bar(0, 0, 640, 480, 0); @@ -1337,7 +1299,6 @@ void redraw_scene() if (one_buffer) RestoreScreen(); OutBuffer2nd(); if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); - if (show_debug) debug_print(); other_draw(); if (cur_mode == MD_END_GAME) { death_screen(); diff --git a/game/console.c b/game/console.c index bebea6b..1e14055 100644 --- a/game/console.c +++ b/game/console.c @@ -10,7 +10,7 @@ void macro_drop_item(int sector,int smer,short item); /****/ -static void wzprintf(const char *text,...); +void wzprintf(const char *text,...) __attribute__((format(printf, 1, 2))); static void wzputs(const char *text); char *side_flags[]= @@ -476,7 +476,7 @@ static int add_file_to_console(const char *name, LIST_FILE_TYPE _, size_t __, vo static int process_on_off_command(const char *cmd, char on) { if (istrcmp(cmd, "inner-eye") == 0) { - show_debug = on; + log_combat = on; return 1; } if (istrcmp(cmd, "hunter-instinct") == 0) { @@ -659,7 +659,7 @@ static void wiz_find_monster(const char *name) { for (size_t i = 0; i home_pos,0,0); add_spectxtr(m->home_pos,H_TELEP_PCX,14,1,0); refresh_mob_map(); - debug_text="New monster arrived to the dungeon !"; SEND_LOG("(RELOAD) Mob reloaded: '%s' at sector %d",m->name,m->home_pos); free_path(m-mobs); } @@ -1360,65 +1359,76 @@ void mob_check_death(int num,TMOB *p) } extern char att_player; -void mob_hit(TMOB *mm,int dostal) - { - int ch; - int mob_dostal=0,mob_dostal_pocet=0; +void mob_hit(TMOB *mm, int dostal) { + int ch; + int mob_dostal = 0, mob_dostal_pocet = 0; - if (mm->vlajky & MOB_PASSABLE) return; - if (dostal>mm->vlastnosti[VLS_MAXHIT]) dostal=mm->vlastnosti[VLS_MAXHIT]; - mm->headx=mm->locx; - mm->heady=mm->locy; - mm->lives-=dostal; - mob_dostal_pocet=dostal; - mm->dostal+=dostal; - if (dostal>0) mm->vlajky|=MOB_IN_BATTLE; - //mm->stay_strategy|=MOB_WALK | MOB_WATCH; - mm->dialog_flags|=0x2; - if (mm->lives>mm->vlastnosti[VLS_MAXHIT]) mm->lives=mm->vlastnosti[VLS_MAXHIT]; - dlives=mm->lives; - if (dostal>0) - { - ddostal=dostal; - send_experience(mm,dostal); - att_player=select_player; - if (dostallives) ch=dostal*3/mm->lives;else ch=2; - mob_dostal=ch+1; - bott_draw(0); - if (mm->lives<1) - { - int xpos = 0; - switch (viewdir) - { - case 0:xpos=-(mm->locx-128);break; - case 1:xpos=-(mm->locy-128);break; - case 2:xpos=(mm->locx-128);break; - case 3:xpos=(mm->locy-128);break; - } - add_spectxtr(mm->sector,H_KILL,10,1,xpos*23/10); - mm->anim_phase=MOB_DEATH; + if (mm->vlajky & MOB_PASSABLE) + return; + if (dostal > mm->vlastnosti[VLS_MAXHIT]) + dostal = mm->vlastnosti[VLS_MAXHIT]; + mm->headx = mm->locx; + mm->heady = mm->locy; + mm->lives -= dostal; + mob_dostal_pocet = dostal; + mm->dostal += dostal; + if (dostal > 0) + mm->vlajky |= MOB_IN_BATTLE; + //mm->stay_strategy|=MOB_WALK | MOB_WATCH; + mm->dialog_flags |= 0x2; + if (mm->lives > mm->vlastnosti[VLS_MAXHIT]) + mm->lives = mm->vlastnosti[VLS_MAXHIT]; + if (log_combat) wzprintf("%s was hit: %d, lives: %d\n", mm->name, dostal, mm->lives); + if (dostal > 0) { + send_experience(mm, dostal); + att_player = select_player; + if (dostal < mm->lives) + ch = dostal * 3 / mm->lives; + else + ch = 2; + mob_dostal = ch + 1; + bott_draw(0); + if (mm->lives < 1) { + int xpos = 0; + switch (viewdir) { + case 0: + xpos = -(mm->locx - 128); + break; + case 1: + xpos = -(mm->locy - 128); + break; + case 2: + xpos = (mm->locx - 128); + break; + case 3: + xpos = (mm->locy - 128); + break; + } + add_spectxtr(mm->sector, H_KILL, 10, 1, xpos * 23 / 10); + mm->anim_phase = MOB_DEATH; + } else + mm->anim_phase = MOB_TO_HIT; + mm->anim_counter = 0; + mm->mode = MBA_NONE; + mob_sound_event(mm, MBS_HIT); + battle |= dostal > 0; + if (vybrana_zbran > -1) //utok zbrani? + { + int druh; + if (vybrana_zbran != 0) //neni to utok holyma rukama + { + TITEM *it; + it = &glob_items[vybrana_zbran - 1]; + druh = it->typ_zbrane; + } else + druh = TPW_OST; + send_weapon_skill(druh); + vybrana_zbran = -1; } - else mm->anim_phase=MOB_TO_HIT; - mm->anim_counter=0; - mm->mode=MBA_NONE; - mob_sound_event(mm,MBS_HIT); - battle|=dostal>0; - if (vybrana_zbran>-1) //utok zbrani? - { - int druh; - if (vybrana_zbran!=0) //neni to utok holyma rukama - { - TITEM *it; - it=&glob_items[vybrana_zbran-1]; - druh=it->typ_zbrane; - } - else druh=TPW_OST; - send_weapon_skill(druh); - vybrana_zbran=-1; - } - } - if (mob_dostal_pocet>0)draw_blood(1,mob_dostal,mob_dostal_pocet); - } + } + if (mob_dostal_pocet > 0) + draw_blood(1, mob_dostal, mob_dostal_pocet); +} void mob_strelba(TMOB *p) @@ -2169,6 +2179,7 @@ int utok_na_sektor(THUMAN *p,TMOB *mm,int ch,int bonus) if (mm->vlastnosti[VLS_KOUZLA] & SPL_OKO) //oko za oko pro potvoru { p->lives-=dostal; + if (log_combat) wzprintf("%s was hit (eye for an eye): %d\n", p->jmeno, dostal); player_check_death(p,0); } if (dostal) @@ -2177,18 +2188,22 @@ int utok_na_sektor(THUMAN *p,TMOB *mm,int ch,int bonus) play_sample_at_sector(H_SND_SWHIT1+rnd(2),viewsector,viewsector,0,0); if (p->vlastnosti[VLS_KOUZLA] & SPL_DRAIN) { - p->lives+=dostal*8/(rnd(16)+16); + int drain_roll = rnd(16)+16; + int drain = dostal*8/drain_roll; + p->lives+=drain; + if (log_combat) wzprintf("%s received (live drain): %d(hit) x 8 / %d(drain_roll) = %d HP\n", + p->jmeno, dostal, drain_roll, drain); if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT]; } } else { - ddostal=0; + dostal=0; play_sample_at_sector(H_SND_SWMISS1+rnd(2),viewsector,viewsector,0,0); } mm->vlajky|=MOB_IN_BATTLE; neco_v_pohybu=1; - return ddostal; + return dostal; } void sleep_enemy(char regen) diff --git a/game/gamesave.c b/game/gamesave.c index fd2ed6a..827bc62 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -942,7 +942,9 @@ static char is_same_prefix(const char *name, const char *prev_name) { } static int get_all_savegames_callback(const char *name, LIST_FILE_TYPE type , size_t size, void *ctx) { - if (istrncmp(name, "sav.", 4) != 0) return 1; + if (istrncmp(name, "sav.", 4) != 0 + && istrcmp(name+strlen(name)-4,".sav") != 0) + return 0; TSAVEGAME_CB_STATE *st = (TSAVEGAME_CB_STATE *)ctx; if (st->prefix_len == 0 || strncmp(name, st->prefix, st->prefix_len) == 0) { str_replace(&(st->files), st->count, name); @@ -1006,7 +1008,7 @@ static void load_specific_file(int slot_num,char *filename,void **out,int32_t *s static TSAVEGAME_LIST get_all_savegames(unsigned long kampan) { //sav.creation_time.game_save_time char prefix[50]; - snprintf(prefix,500,"sav.%010lx.",kampan); + snprintf(prefix,50,"sav.%010lx.",kampan); TSAVEGAME_CB_STATE st; st.files = create_list(32); st.prefix = kampan?prefix:NULL; diff --git a/game/globals.h b/game/globals.h index e1c3cea..f4bad5d 100644 --- a/game/globals.h +++ b/game/globals.h @@ -627,26 +627,7 @@ extern int autoopendata; extern char doNotLoadMapState; -//debug !!!!! -extern int dhit; -extern int ddef; -extern int ddostal; -extern int dlives; -extern int dmzhit; -extern int dsee; -extern char show_debug; -extern char *debug_text; -extern char map_with_password; -extern int debug_enabled; -extern char marker; //tato promenna je 0, jen v pripade ze je 1 probehne assert -#define MARKER_SET() {SEND_LOG("(MARKER) Marker Sets",0,0);marker=1;} -#define MARKER_RESET() {SEND_LOG("(MARKER) Marker Resets",0,0);marker=0;} -#define MARKER_HIT(action) if (marker) \ - { \ - SEND_LOG("(MARKER) Marker hit!",0,0);\ - action;\ - MARKER_RESET();\ - } +extern char log_combat; //builder - skeldal @@ -1617,6 +1598,7 @@ THUMAN *isplayer(int sector,THUMAN *h,char death); Death=1 pocita i mrtvoly */ int trace_path(int sector,int dir); //zjistuje zda je mozne strilet +void wzprintf(const char *text,...) __attribute__((format(printf, 1, 2))); int numplayers(int sector,char death); diff --git a/game/inv.c b/game/inv.c index 58e144d..b226278 100644 --- a/game/inv.c +++ b/game/inv.c @@ -2050,8 +2050,8 @@ int weigth_defect(THUMAN *p) } static char check_double_wield() { - short i1 = human_selected->wearing[PO_RUKA_L]; - short i2 = human_selected->wearing[PO_RUKA_R]; + short i1 = human_selected->wearing[PO_RUKA_L]-1; + short i2 = human_selected->wearing[PO_RUKA_R]-1; if (!i1 || !i2) return 0; const TITEM *it1 = glob_items+i1; const TITEM *it2 = glob_items+i2; diff --git a/game/souboje.c b/game/souboje.c index a42c909..bcaf06f 100644 --- a/game/souboje.c +++ b/game/souboje.c @@ -317,7 +317,6 @@ char q_zacit_souboj(TMOB *p,int d,short sector) 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; @@ -356,6 +355,13 @@ int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int exter int zasah,mutok,flg; flg=obrance[VLS_KOUZLA]; short attack_attribute = MAX(utocnik[VLS_SILA], utocnik[VLS_OBRAT]); + int utok,obrana; + int ospod; + int attack_roll,defense_roll,mag_att_roll,mg_def; + int dmzhit = 0; + int ddostal = 0; + int disadv = 0; + /* if (game_extras & EX_ALTERNATEFIGHT) { int postih=(chaos+1)/2; @@ -380,45 +386,68 @@ int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int exter dmzhit=mutok; zasah=utok-obrana; } - else + else*/ { - int utok,obrana; - int ospod; - int attack_roll,defense_roll,mag_att_roll,mg_def; - chaos=(chaos+1)/2; //chaos - pocet postav, 0=>1, 1=>1,2=>1,3=>2,4=>2,5=>3,6=>3 + disadv=(chaos+1)/2; //chaos - pocet postav, 0=>1, 1=>1,2=>1,3=>2,4=>2,5=>3,6=>3 //nizsi obrana je snizena o pocet postav na poli //0-2=>no change, 3-4=>/2, 5-6=>/3 - ospod=obrance[VLS_OBRAN_L]/chaos; - attack_roll=rnd(utocnik[VLS_UTOK_H]-utocnik[VLS_UTOK_L]+1); - defense_roll=rnd(obrance[VLS_OBRAN_H]-ospod+1); - mag_att_roll=rnd(utocnik[VLS_MGSIL_H]-utocnik[VLS_MGSIL_L]+1); + ospod=obrance[VLS_OBRAN_L]/disadv; + attack_roll=utocnik[VLS_UTOK_L]+rnd(utocnik[VLS_UTOK_H]-utocnik[VLS_UTOK_L]+1); + defense_roll=ospod+rnd(obrance[VLS_OBRAN_H]-ospod+1); + mag_att_roll=utocnik[VLS_MGSIL_L]+rnd(utocnik[VLS_MGSIL_H]-utocnik[VLS_MGSIL_L]+1); //hit=attack_roll+max(str,dex)+external_force - dhit=utok=utocnik[VLS_UTOK_L]+attack_roll+attack_attribute/5+external_force; + utok=attack_roll+attack_attribute/5+external_force; //def=defense_roll+dex/5+(10 if invisible) - obrana=ospod+defense_roll+(obrance[VLS_OBRAT]/5)+(flg & SPL_INVIS?10:0); + obrana=defense_roll+(obrance[VLS_OBRAT]/5)+(flg & SPL_INVIS?10:0); //mg_attack = magic_roll - mutok=utocnik[VLS_MGSIL_L]+mag_att_roll; + mutok=mag_att_roll+(mag_att_roll?(utocnik[VLS_SMAGIE]/5):0); //mg_deffense (100-x) - mg_def=mgochrana(obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]]); + mg_def=obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]]; //adjust magic attack - mutok=mg_def*mutok/100; - dmzhit=mutok; - zasah=utok-(ddef=obrana); + dmzhit=mgochrana(mg_def)*mutok/100; + zasah=utok-obrana; } if (zasah<0) zasah=0; - if (zasah>0) zasah+=utocnik[VLS_DAMAGE],zasah=MAX(zasah,1); + int damage = utocnik[VLS_DAMAGE]+zbran; + if (zasah<0 || damage<0) damage = 0; ddostal=zasah; - if (flg & SPL_SANC) zasah/=2; - zasah=zasah+mutok; - if (zasah>0) - { - zasah+=zbran; - if (zasah<1) zasah=1; - } - if (flg & SPL_HSANC) zasah/=2; - if (flg & SPL_TVAR) zasah=-zasah; + zasah+=damage; + if (log_combat) { + wzprintf("Combat: Attack roll (%d-%d) = %d, " + "Defense disadv.: %d*2/(%d+1)=%d , " + "Defense roll (%d-%d) = %d, " + "Magic roll (%d-%d) = %d\n", + (int)utocnik[VLS_UTOK_L],(int)utocnik[VLS_UTOK_H],attack_roll, + (int)obrance[VLS_OBRAN_L],chaos, ospod, + ospod,(int)obrance[VLS_OBRAN_H], defense_roll, + (int)utocnik[VLS_MGSIL_L],(int)utocnik[VLS_MGSIL_H], mag_att_roll); + wzprintf("Combat: phys.hit: %d(att.roll) + %d(%s)/5 +%d(ext.force) - %d(def.roll)-%d(%s)/5 + %d(damage)=%d(%d)\n", + attack_roll, attack_attribute, + attack_attribute==utocnik[VLS_SILA]?texty[10]:texty[13], + external_force, defense_roll, (int)obrance[VLS_OBRAT], + texty[13], damage, utok-obrana, zasah); + if (mag_att_roll) { + wzprintf("Combat: %d(magic roll) + %d(%s)/5 = %d, magic resistance = %d(%s), magic hit: %d * (100 - %d)/100 = %d\n", + mag_att_roll, (int)utocnik[VLS_SMAGIE], texty[11], mutok, mg_def,texty[22+utocnik[VLS_MGZIVEL]], mutok, mg_def, dmzhit); + + } + } + if (flg & SPL_SANC) { + zasah/=2; + if (log_combat) wzprintf("Physical resistance applied: %d/2 = %d", ddostal, zasah); + ddostal = zasah; + } + zasah=zasah+dmzhit; + if (flg & SPL_HSANC) { + zasah/=2; + if (log_combat) wzprintf("Total resistance applied: %d/2 = %d", ddostal, zasah); + } + if (flg & SPL_TVAR) { + if (log_combat) wzprintf("Set Face spell applied: %d = -%d (heal)", zasah, zasah); + zasah=-zasah; + } return zasah; } @@ -952,7 +981,7 @@ void hod_dykou(THUMAN *p,int where,int bonus) 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->hit_bonus=p->vlastnosti[VLS_OBRAT]/10+bonus; v->damage=0; for(i=0;iinv_size;i++) { @@ -971,6 +1000,11 @@ void hod_dykou(THUMAN *p,int where,int bonus) } if(i==p->inv_size) p->wearing[where]=0; picked_item=pp; + if (log_combat) { + wzprintf("%s throws: ext.force: %d(%s)/10+%d(bonus) = %d\n", + p->jmeno, p->vlastnosti[VLS_OBRAT], texty[13], + bonus, v->hit_bonus); + } } void vystrel_sip(THUMAN *p,int bonus) @@ -978,7 +1012,7 @@ void vystrel_sip(THUMAN *p,int bonus) short *pp; int ps; int i; - int x; + int attack_roll; LETICI_VEC *v; TITEM *t; @@ -1002,8 +1036,8 @@ void vystrel_sip(THUMAN *p,int bonus) 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; + attack_roll=p->vlastnosti[VLS_UTOK_L]+rnd(p->vlastnosti[VLS_UTOK_H]-p->vlastnosti[VLS_UTOK_L]); + v->hit_bonus=attack_roll+(p->vlastnosti[VLS_OBRAT]/5)+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 @@ -1011,6 +1045,15 @@ void vystrel_sip(THUMAN *p,int bonus) 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; + + if (log_combat) { + wzprintf("%s shoots: attack_roll (%d-%d)=%d, ext.force: %d + %d(%s)/5+%d(bonus) = %d\n", + p->jmeno, p->vlastnosti[VLS_UTOK_L], p->vlastnosti[VLS_UTOK_H], + attack_roll, + attack_roll, p->vlastnosti[VLS_OBRAT], texty[13], + bonus, v->hit_bonus); + } + } char is_useable_weapon(int i) @@ -1313,7 +1356,9 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje case AC_THROW: { int x,y; - memcpy(&picked_item,&p->provadena_akce->data2,sizeof(short *)); + picked_item = getmem(sizeof(short)*2); + picked_item[0] = p->provadena_akce->data2; + picked_item[1] = 0; x=p->provadena_akce->data1; y=(x>>8)*2;x=(x & 0xff)*4; prejdi_na_pohled(p); @@ -1800,7 +1845,9 @@ void zrusit_akce() if (c->action==AC_THROW) { poloz_vsechny_predmety(); - memcpy(&picked_item,&c->data2,sizeof(short *)); + picked_item = getmem(sizeof(short)*2); + picked_item[0] = c->data2; + picked_item[1] = 0; c++; } else c++; @@ -1818,10 +1865,13 @@ char souboje_clk_throw(int id,int xa,int ya,int xr,int yr) if (postavy[select_player].actions==0) return 0; if (picked_item==NULL) return 0; + if (picked_item[1] != 0) 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->data2 = picked_item[0]; + free(picked_item); + picked_item = NULL; c->data1=xa/4+(ya/2)*256; c++; c->action=0; @@ -2396,6 +2446,9 @@ void send_experience(TMOB *p,int dostal) if (p->lives<=0) { int i; + if (log_combat && p->bonus) { + wzprintf("Group experience: %d\n", p->bonus); + } for(i=0;ibonus; @@ -2407,7 +2460,14 @@ void send_experience(TMOB *p,int dostal) player_check_death(postavy+select_player,0); } } - if (dostal>0) postavy[select_player].exp+=(int32_t)((float)p->experience*(float)dostal/p->vlastnosti[VLS_MAXHIT]); + if (dostal>0) { + int exp = ((float)p->experience*(float)dostal/p->vlastnosti[VLS_MAXHIT]); + if (log_combat && p->bonus) { + wzprintf("%s experience: %d\n", postavy[select_player].jmeno, p->bonus); + } + + postavy[select_player].exp+=(int32_t)exp; + } check_player_new_level(&postavy[select_player]); } diff --git a/game/wizard.c b/game/wizard.c index ac60506..6b569cb 100644 --- a/game/wizard.c +++ b/game/wizard.c @@ -429,7 +429,7 @@ void wizard_kbd(EVENT_MSG *msg,void **usr) switch (c) { case 'C': - case '<':show_debug=!show_debug;break; + case '<':log_combat=!log_combat;break; case '=':show_lives=!show_lives;break; case '>':if (mman_action!=NULL) mman_action=NULL;else mman_action=mman_scan;break; case '@':set_immortality();set_nohassle();break;