support for various kinds of arrows

This commit is contained in:
Ondřej Novák 2025-06-20 10:40:43 +02:00
parent c1197ed78e
commit 65b0cd27fc
6 changed files with 122 additions and 40 deletions

View file

@ -229,6 +229,7 @@ static void generate_vlastnosti(THUMAN *p, int povolani)
p->used=1; p->used=1;
p->groupnum=1; p->groupnum=1;
p->sipy=0; p->sipy=0;
p->sip_druh = 0;
p->inv_size=6; p->inv_size=6;
p->level=1; p->level=1;
p->exp=rnd(200); p->exp=rnd(200);

View file

@ -1461,14 +1461,27 @@ void mob_strelba(TMOB *p)
int i; int i;
TITEM *t; TITEM *t;
for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].druh==TYP_VRHACI) break;
if (i==item_count) for(i=0;i<(int)countof(p->inv);++i) {
{ int itm = p->inv[i];
closemode(); if (itm) {
display_error("Nestvura nemuze strilet. Neni nadefinovan obekt sipu"); t = &glob_items[itm-1];
exit(1); if (t->druh == TYP_VRHACI && t->umisteni == PL_SIP && t->user_value <= 1) break;
} t = NULL;
t=glob_items+i; }
}
if (t == 0) {
for(i=0;i<item_count;i++) {
t = &glob_items[i];
if (t->umisteni == 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_H]=p->vlastnosti[VLS_MGSIL_H]; //adjust zmen v magickem utoku
t->zmeny[VLS_MGSIL_L]=p->vlastnosti[VLS_MGSIL_L]; t->zmeny[VLS_MGSIL_L]=p->vlastnosti[VLS_MGSIL_L];
t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL]; t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL];

View file

@ -917,7 +917,7 @@ typedef struct titem
short keynum; //148 cislo klice short keynum; //148 cislo klice
short polohy[2][2]; //156 souradnice poloh pro zobrazeni v inv short polohy[2][2]; //156 souradnice poloh pro zobrazeni v inv
uint8_t typ_zbrane; //160 Typ zbrane 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 sound; //cislo zvuku
short v_letu[16]; //192 short v_letu[16]; //192
unsigned short cena; unsigned short cena;
@ -958,7 +958,8 @@ typedef struct thuman
short stare_vls[VLS_MAX]; //mapa vlastnosti pred korekcemi short stare_vls[VLS_MAX]; //mapa vlastnosti pred korekcemi
short wearing[HUMAN_PLACES]; //nosene predmety short wearing[HUMAN_PLACES]; //nosene predmety
short prsteny[HUMAN_RINGS]; //nosene prsteny 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_size; //velikost inventare 6-30
short inv[MAX_INV]; //inventar short inv[MAX_INV]; //inventar
short level; //uroven short level; //uroven

View file

@ -760,16 +760,16 @@ char put_item_to_inv(THUMAN *p,short *picked_items)
if (picked_items==NULL) return 0; if (picked_items==NULL) return 0;
if (isdemon(p)) return 0; if (isdemon(p)) return 0;
it=*picked_items; it=*picked_items;
if (it && glob_items[it-1].umisteni==PL_SIP && !neprezbrojit()) if (it && glob_items[it-1].umisteni==PL_SIP && !neprezbrojit()) {
{ int u=glob_items[it-1].user_value;if (!u) u=1;
int u; uint8_t sip_druh = glob_items[it-1].druh_sipu;
u=glob_items[it-1].user_value;if (!u) u=1; if (p->sipy+u<100 && (p->sip_druh == sip_druh || p->sipy == 0))
if (p->sipy+u<100) {
{ p->sipy+=u;
p->sipy+=u; p->sip_druh = sip_druh;
return 1; return 1;
} }
} }
for(i=0;picked_items[i];i++); for(i=0;picked_items[i];i++);
while (i) while (i)
{ {
@ -1817,9 +1817,11 @@ static char uloz_sip_action(char fast_key) {
if (neprezbrojit()) return 0; if (neprezbrojit()) return 0;
if (picked_item!=NULL && picked_item[1]==0 && glob_items[picked_item[0]-1].umisteni==PL_SIP) { 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 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 (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->sipy+=pocet;
human_selected->sip_druh = druh;
free(picked_item); free(picked_item);
picked_item=NULL; picked_item=NULL;
} else { } else {
@ -1833,7 +1835,8 @@ static char uloz_sip_action(char fast_key) {
for (int i = 0; i < item_count; ++i) { for (int i = 0; i < item_count; ++i) {
if (glob_items[i].umisteni == PL_SIP if (glob_items[i].umisteni == PL_SIP
&& glob_items[i].user_value > max_arrows && 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; max_arrows = glob_items[i].user_value;
best_item = i; best_item = i;
} }
@ -1845,7 +1848,7 @@ static char uloz_sip_action(char fast_key) {
human_selected->sipy-=max_arrows; human_selected->sipy-=max_arrows;
} }
} else { } else {
for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].user_value==0) for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].user_value<=1 && glob_items[i].druh_sipu == human_selected->sip_druh)
{ {
picked_item=(short *)getmem(2*sizeof(short)); picked_item=(short *)getmem(2*sizeof(short));
picked_item[0] = i+1; picked_item[0] = i+1;
@ -1853,8 +1856,12 @@ static char uloz_sip_action(char fast_key) {
human_selected->sipy--; human_selected->sipy--;
break; break;
} }
if (picked_item == NULL) {
human_selected->sipy = 0;
} }
} }
}
} }
pick_set_cursor(); pick_set_cursor();
inv_redraw(); inv_redraw();

View file

@ -1032,19 +1032,21 @@ void vystrel_sip(THUMAN *p,int bonus)
int attack_roll; int attack_roll;
LETICI_VEC *v; LETICI_VEC *v;
TITEM *t; TITEM *t;
char err = 0;
ps=trace_path(p->sektor,p->direction); ps=trace_path(p->sektor,p->direction);
if (ps==-255) return; if (ps==-255) return;
if (!p->sipy)
{
char s[100];
sprintf(s,texty[72],p->jmeno); if (!p->sipy) err = 1;
bott_disp_text(s); for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].druh == TYP_VRHACI && glob_items[i].druh_sipu == p->sip_druh) break;
return; if (i==item_count) err = 1;
} if (err) {
for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].user_value==0) break; char s[100];
if (i==item_count) return;
sprintf(s,texty[72],p->jmeno);
bott_disp_text(s);
return;
}
t=glob_items+i; t=glob_items+i;
pp=picked_item; pp=picked_item;
picked_item=getmem(2*sizeof(short)); picked_item=getmem(2*sizeof(short));

View file

@ -125,6 +125,7 @@ typedef struct ddlmap_info {
const void *ptr; const void *ptr;
size_t size; size_t size;
TNAMETABLE_REF nametable; TNAMETABLE_REF nametable;
char *path;
} TDDLMAP_INFO; } TDDLMAP_INFO;
#define MAX_PATCHES 4 #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) { for (int i = 0; i < MAX_PATCHES; ++i) {
if (ddlmap[i].ptr == NULL) { if (ddlmap[i].ptr == NULL) {
ddlmap[i].ptr = bmf; ddlmap[i].ptr = bmf;
ddlmap[i].size = sz; ddlmap[i].size = sz;
ddlmap[i].nametable = load_file_table(bmf); ddlmap[i].nametable = load_file_table(bmf);
ddlmap[i].path = strdup(filename);
return; return;
} }
} }
@ -290,7 +292,7 @@ char add_patch_file(const char *filename) {
size_t bmf_s; size_t bmf_s;
const void *bmf = map_file_to_memory(file_icase_find(filename), &bmf_s); const void *bmf = map_file_to_memory(file_icase_find(filename), &bmf_s);
if (bmf) { if (bmf) {
add_patch(bmf, bmf_s); add_patch(bmf, bmf_s, filename);
return 1; return 1;
} }
return 0; return 0;
@ -303,6 +305,45 @@ void init_manager(void) {
memset(ddlmap,0,sizeof(ddlmap)); memset(ddlmap,0,sizeof(ddlmap));
} }
void reload_ddls(void) {
int i,j;
THANDLE_DATA *p;
for(i=0;i<BK_MAJOR_HANDLES;i++) if (_handles[i]!=NULL) {
p=(THANDLE_DATA *)(_handles[i]);
for(j=0;j<BK_MINOR_HANDLES;j++) {
THANDLE_DATA *h = p+j;
if (h->status == 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) 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); entr = get_file_entry(group, d, &hd);
if (entr!=0) if (entr!=0)
{ {
SEND_LOG("(LOAD) Afile is loading file '%s' from group %d",d,group); SEND_LOG("(LOAD) Afile is loading file '%s' from group %d",d,group);
const TDDLMAP_INFO *nfo = &ddlmap[hd.src_index]; const TDDLMAP_INFO *nfo = &ddlmap[hd.src_index];
const int32_t * szptr = (const int32_t *)((const char *)nfo->ptr+hd.offset); const int32_t * szptr = (const int32_t *)((const char *)nfo->ptr+hd.offset);
*blocksize = *szptr; *blocksize = *szptr;
return szptr+1; return szptr+1;
} }
else if (mman_pathlist!=NULL) { else if (mman_pathlist!=NULL) {
const char *name = build_pathname(2,mman_pathlist[group],d); 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) { if (h->loadproc) {
int32_t sz = h->size; int32_t sz = h->size;
const void *r = h->loadproc(h->blockdata, &sz, handle); 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) { if (r != h->blockdata) {
ablock_free(h->blockdata); ablock_free(h->blockdata);
h->blockdata = r; h->blockdata = r;
@ -500,6 +545,11 @@ const void *ablock(int handle)
h->status=BK_PRESENT; h->status=BK_PRESENT;
h->size=s; h->size=s;
decompress_data(h, handle); 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; return h->blockdata;
} }
} }
@ -538,7 +588,14 @@ void aunlock(int handle)
if (!h->lockcount) if (!h->lockcount)
{ {
h->flags&=~BK_LOCKED; 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); if (h->status==BK_SAME_AS) aunlock(h->offset);
} }
//SEND_LOG("(LOCK) Handle unlocked %04X (count %d)",handle,h->lockcount); //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) { for (int i = 0; i < MAX_PATCHES; ++i) {
unmap_file((void *)ddlmap[i].ptr, ddlmap[i].size); unmap_file((void *)ddlmap[i].ptr, ddlmap[i].size);
free(ddlmap[i].path);
} }
max_handle=0; max_handle=0;