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->groupnum=1;
p->sipy=0;
p->sip_druh = 0;
p->inv_size=6;
p->level=1;
p->exp=rnd(200);

View file

@ -1461,14 +1461,27 @@ void mob_strelba(TMOB *p)
int i;
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)
{
closemode();
display_error("Nestvura nemuze strilet. Neni nadefinovan obekt sipu");
exit(1);
for(i=0;i<(int)countof(p->inv);++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;
}
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_L]=p->vlastnosti[VLS_MGSIL_L];
t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL];

View file

@ -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

View file

@ -760,13 +760,13 @@ 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)
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;
}
}
@ -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;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[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();

View file

@ -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)
{
if (!p->sipy) err = 1;
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;
if (i==item_count) err = 1;
if (err) {
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));

View file

@ -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;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)
@ -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;