diff --git a/game/chargen2.c b/game/chargen2.c index aab09e4..c1ff34d 100644 --- a/game/chargen2.c +++ b/game/chargen2.c @@ -229,6 +229,7 @@ static void generate_vlastnosti(THUMAN *p, int povolani) p->used=1; p->groupnum=1; p->sipy=0; + p->sip_druh = 0; p->inv_size=6; p->level=1; p->exp=rnd(200); diff --git a/game/enemy.c b/game/enemy.c index b4868ed..df2e665 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -1461,14 +1461,27 @@ void mob_strelba(TMOB *p) int i; TITEM *t; - for(i=0;iinv);++i) { + int itm = p->inv[i]; + if (itm) { + t = &glob_items[itm-1]; + if (t->druh == TYP_VRHACI && t->umisteni == PL_SIP && t->user_value <= 1) break; + t = NULL; + } + } + if (t == 0) { + for(i=0;iumisteni == PL_SIP && t->druh == TYP_VRHACI && t->user_value <= 1) break; + t = NULL; + } + } + if (t == NULL) { + bott_disp_text("Enemy has no arrows. Put an arrow to their inventory"); + return; + } + 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]; diff --git a/game/globals.h b/game/globals.h index 17670a4..73623a0 100644 --- a/game/globals.h +++ b/game/globals.h @@ -917,7 +917,7 @@ typedef struct titem short keynum; //148 cislo klice short polohy[2][2]; //156 souradnice poloh pro zobrazeni v inv uint8_t typ_zbrane; //160 Typ zbrane - char unused; + uint8_t druh_sipu; //pridano, aby slo vytvaret ruzne sipy a toulce (bylo unused) short sound; //cislo zvuku short v_letu[16]; //192 unsigned short cena; @@ -958,7 +958,8 @@ typedef struct thuman short stare_vls[VLS_MAX]; //mapa vlastnosti pred korekcemi short wearing[HUMAN_PLACES]; //nosene predmety short prsteny[HUMAN_RINGS]; //nosene prsteny - short sipy; //pocet sipu v toulci + uint8_t sipy; //pocet sipu v toulci + uint8_t sip_druh; //druh sipu v toulci short inv_size; //velikost inventare 6-30 short inv[MAX_INV]; //inventar short level; //uroven diff --git a/game/inv.c b/game/inv.c index 9292e4b..641a059 100644 --- a/game/inv.c +++ b/game/inv.c @@ -760,16 +760,16 @@ char put_item_to_inv(THUMAN *p,short *picked_items) if (picked_items==NULL) return 0; if (isdemon(p)) return 0; it=*picked_items; - if (it && glob_items[it-1].umisteni==PL_SIP && !neprezbrojit()) - { - int u; - u=glob_items[it-1].user_value;if (!u) u=1; - if (p->sipy+u<100) - { - p->sipy+=u; - return 1; - } - } + if (it && glob_items[it-1].umisteni==PL_SIP && !neprezbrojit()) { + int u=glob_items[it-1].user_value;if (!u) u=1; + uint8_t sip_druh = glob_items[it-1].druh_sipu; + if (p->sipy+u<100 && (p->sip_druh == sip_druh || p->sipy == 0)) + { + p->sipy+=u; + p->sip_druh = sip_druh; + return 1; + } + } for(i=0;picked_items[i];i++); while (i) { @@ -1817,9 +1817,11 @@ static char uloz_sip_action(char fast_key) { if (neprezbrojit()) return 0; if (picked_item!=NULL && picked_item[1]==0 && glob_items[picked_item[0]-1].umisteni==PL_SIP) { int pocet=glob_items[picked_item[0]-1].user_value; + int druh=glob_items[picked_item[0]-1].druh_sipu; if (pocet==0) pocet=1; - if (human_selected->sipy+pocet>99) return 1; + if (human_selected->sipy+pocet>99 && (human_selected->sip_druh == druh || human_selected->sipy == 0)) return 1; human_selected->sipy+=pocet; + human_selected->sip_druh = druh; free(picked_item); picked_item=NULL; } else { @@ -1833,7 +1835,8 @@ static char uloz_sip_action(char fast_key) { for (int i = 0; i < item_count; ++i) { if (glob_items[i].umisteni == PL_SIP && glob_items[i].user_value > max_arrows - && glob_items[i].user_value <= human_selected->sipy) { + && glob_items[i].user_value <= human_selected->sipy + && glob_items[i].druh_sipu == human_selected->sip_druh) { max_arrows = glob_items[i].user_value; best_item = i; } @@ -1845,7 +1848,7 @@ static char uloz_sip_action(char fast_key) { human_selected->sipy-=max_arrows; } } else { - for(i=0;isip_druh) { picked_item=(short *)getmem(2*sizeof(short)); picked_item[0] = i+1; @@ -1853,8 +1856,12 @@ static char uloz_sip_action(char fast_key) { human_selected->sipy--; break; } + if (picked_item == NULL) { + human_selected->sipy = 0; } } + + } } pick_set_cursor(); inv_redraw(); diff --git a/game/souboje.c b/game/souboje.c index 6cd3890..86f4b44 100644 --- a/game/souboje.c +++ b/game/souboje.c @@ -1032,19 +1032,21 @@ void vystrel_sip(THUMAN *p,int bonus) int attack_roll; LETICI_VEC *v; TITEM *t; + char err = 0; 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;isipy) err = 1; + for(i=0;isip_druh) break; + if (i==item_count) err = 1; + if (err) { + char s[100]; + + sprintf(s,texty[72],p->jmeno); + bott_disp_text(s); + return; + } t=glob_items+i; pp=picked_item; picked_item=getmem(2*sizeof(short)); @@ -2116,7 +2118,7 @@ static void zahajit_kolo(char prekvapeni) rozhodni_o_poradi(); unwire_proc(); wire_jadro_souboje(); - + } static char add_pc_action(int d) { diff --git a/libs/memman.c b/libs/memman.c index 7d6b632..4d4d54f 100644 --- a/libs/memman.c +++ b/libs/memman.c @@ -125,6 +125,7 @@ typedef struct ddlmap_info { const void *ptr; size_t size; TNAMETABLE_REF nametable; + char *path; } TDDLMAP_INFO; #define MAX_PATCHES 4 @@ -273,12 +274,13 @@ THANDLE_DATA *zneplatnit_block(int handle) } -static void add_patch(const void *bmf, size_t sz) { +static void add_patch(const void *bmf, size_t sz, const char *filename) { for (int i = 0; i < MAX_PATCHES; ++i) { if (ddlmap[i].ptr == NULL) { ddlmap[i].ptr = bmf; ddlmap[i].size = sz; ddlmap[i].nametable = load_file_table(bmf); + ddlmap[i].path = strdup(filename); return; } } @@ -290,7 +292,7 @@ char add_patch_file(const char *filename) { size_t bmf_s; const void *bmf = map_file_to_memory(file_icase_find(filename), &bmf_s); if (bmf) { - add_patch(bmf, bmf_s); + add_patch(bmf, bmf_s, filename); return 1; } return 0; @@ -303,6 +305,45 @@ void init_manager(void) { memset(ddlmap,0,sizeof(ddlmap)); } +void reload_ddls(void) { + int i,j; + THANDLE_DATA *p; + + for(i=0;istatus == BK_PRESENT && h->blockdata) { + if (need_to_be_free(h->blockdata)) { + if (!(h->flags & BK_LOCKED)) { + free((void *)h->blockdata); + } else { + h->flags |= BK_KILL_ON_UNLOCK; + } + } else if (h->flags & BK_LOCKED) { + display_error("Reload ddls cannot be perfomed, locked blocks %s", h->src_file); + return; + } + h->status = BK_NOT_LOADED; + h->blockdata = NULL; + } + } + } + for (int i = 0; i < MAX_PATCHES;++i) { + TDDLMAP_INFO *dinfo = &ddlmap[i]; + if (dinfo->ptr != NULL) { + unmap_file(dinfo->ptr, dinfo->size); + size_t bmf_s; + const void *bmf = map_file_to_memory(file_icase_find(dinfo->path), &bmf_s); + if (bmf == NULL) { + abort(); + } + dinfo->ptr = bmf; + dinfo->size = bmf_s; + dinfo->nametable = load_file_table(bmf); + } + } +} int find_same(const char *name,ABLOCK_DECODEPROC decomp) @@ -388,11 +429,11 @@ static const void *afile2(const char *filename,int group,int32_t *blocksize, cha entr = get_file_entry(group, d, &hd); if (entr!=0) { - SEND_LOG("(LOAD) Afile is loading file '%s' from group %d",d,group); - const TDDLMAP_INFO *nfo = &ddlmap[hd.src_index]; - const int32_t * szptr = (const int32_t *)((const char *)nfo->ptr+hd.offset); - *blocksize = *szptr; - return szptr+1; + SEND_LOG("(LOAD) Afile is loading file '%s' from group %d",d,group); + const TDDLMAP_INFO *nfo = &ddlmap[hd.src_index]; + const int32_t * szptr = (const int32_t *)((const char *)nfo->ptr+hd.offset); + *blocksize = *szptr; + return szptr+1; } else if (mman_pathlist!=NULL) { const char *name = build_pathname(2,mman_pathlist[group],d); @@ -438,6 +479,10 @@ static void decompress_data(THANDLE_DATA *h, int handle) { if (h->loadproc) { int32_t sz = h->size; const void *r = h->loadproc(h->blockdata, &sz, handle); + if (r == NULL && h->blockdata != NULL) { + display_error("Failed to load %s - decompress_data returned NULL", h->src_file); + abort(); + } if (r != h->blockdata) { ablock_free(h->blockdata); h->blockdata = r; @@ -500,6 +545,11 @@ const void *ablock(int handle) h->status=BK_PRESENT; h->size=s; decompress_data(h, handle); + if ((h->flags & BK_LOCKED) && !need_to_be_free(h->blockdata)) { + void *cpy = getmem(h->size); + memcpy(cpy, h->blockdata, h->size); + h->blockdata = cpy; + } return h->blockdata; } } @@ -538,7 +588,14 @@ void aunlock(int handle) if (!h->lockcount) { h->flags&=~BK_LOCKED; + if (h->flags & BK_KILL_ON_UNLOCK) { + ablock_free(h->blockdata); + h->flags &= ~(BK_KILL_ON_UNLOCK); + h->status = BK_NOT_LOADED; + h->blockdata = NULL; + } if (h->status==BK_SAME_AS) aunlock(h->offset); + } //SEND_LOG("(LOCK) Handle unlocked %04X (count %d)",handle,h->lockcount); } @@ -572,6 +629,7 @@ void close_manager() } for (int i = 0; i < MAX_PATCHES; ++i) { unmap_file((void *)ddlmap[i].ptr, ddlmap[i].size); + free(ddlmap[i].path); } max_handle=0;