diff --git a/game/enemy.c b/game/enemy.c index 7a5811c..d2a2a1f 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -1317,18 +1317,24 @@ void vymaz_zasahy(THE_TIMER *q) bott_draw(0); } +static int select_drop_inventory_place(TMOB *p) { + int x,y,pl; + if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1; + if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1; + pl=0;if (x>0) pl++; + if (y>0) pl=3-pl; + return pl; +} + static int drop_inventory(TMOB *p) { - int i,x,y,pl; + int i,pl; short c[]={0,0}; - for(i=-1;iinv[i] || (i<0 && p->money)) { - if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1; - if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1; - pl=0;if (x>0) pl++; - if (y>0) pl=3-pl; + pl = select_drop_inventory_place(p); if (i<0) { int z=(int)p->money+(int)(rnd(40)-20)*(int)p->money/(int)100; @@ -1341,6 +1347,16 @@ static int drop_inventory(TMOB *p) } push_item(p->sector,pl,c); } + } + if (destroyed_items) { + int cnt = count_items_total(destroyed_items); + if (cnt) { + int idx = cnt -1; + pl = select_drop_inventory_place(p); + push_item(p->sector,pl, destroyed_items+idx); + destroyed_items[idx] = 0; + } + } return 0; } diff --git a/game/gamesave.c b/game/gamesave.c index 358f500..f87b217 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -586,6 +586,14 @@ int unpack_all_status(FILE *f) return -1; } +static void save_destroyed_items(TMPFILE_WR *f) { + short c = (short)count_items_total(destroyed_items); + temp_storage_write(&c,sizeof(c), f); + if (c) { + temp_storage_write(destroyed_items,sizeof(short)*c, f); + } +} + int save_basic_info() { TMPFILE_WR *f; @@ -645,11 +653,26 @@ int save_basic_info() for(i=0,h=postavy;idemon_save!=NULL) temp_storage_write(h->demon_save,sizeof(THUMAN)*1,f); //ulozeni polozek s demony res|=save_dialog_info(f); + save_destroyed_items(f); temp_storage_close_wr(f); SEND_LOG("(SAVELOAD) Done... Result: %d",res); return res; } +static int load_destroyed_items(TMPFILE_RD *f) { + int res = 0; + short destroyed_items_count = 0; + temp_storage_read(&destroyed_items_count,sizeof(destroyed_items_count), f); + free(destroyed_items); + destroyed_items = NULL; + if (destroyed_items_count) { + destroyed_items = NewArr(short, destroyed_items_count+1); + res|=temp_storage_read(destroyed_items,destroyed_items_count*sizeof(short), f) != destroyed_items_count*sizeof(short); + destroyed_items[destroyed_items_count] = 0; + } + return res; +} + int load_basic_info() { TMPFILE_RD *f; @@ -698,6 +721,7 @@ int load_basic_info() } } res|=load_dialog_info(f); + res|=load_destroyed_items(f); temp_storage_close_rd(f); viewsector=s.viewsector; viewdir=s.viewdir; diff --git a/game/globals.h b/game/globals.h index 85715ae..b5381bd 100644 --- a/game/globals.h +++ b/game/globals.h @@ -577,6 +577,7 @@ extern int mapsize; //pocet sektoru v mape extern int hl_ptr; //ukazatel na konec staticke tabulky registraci extern int end_ptr; //ukazatel na uplny konec tabulky registraci extern short **map_items; //ukazatel na mapu predmetu +extern short *destroyed_items; //list of destroyed items to be returned to the game extern int default_ms_cursor; //cislo zakladniho mysiho kurzoru extern void (*unwire_proc)(void); //procedura zajistujici odpojeni prave ukoncovane interakce extern void (*wire_proc)(void); //procedura zajistujici pripojeni drive ukoncene interakce @@ -990,10 +991,10 @@ char pick_item_(int id,int xa,int ya,int xr,int yr); void wire_inv_mode(THUMAN *select); void init_inventory(void); void init_items(void); -void push_item(int sect,int pos,short *picked_item); +void push_item(int sect,int pos,const short *picked_item); void pop_item(int sect,int pos,int mask,short **picked_item); -int count_items_inside(short *place); -int count_items_total(short *place); +int count_items_inside(const short *place); +int count_items_total(const short *place); char put_item_to_inv(THUMAN *p,short *picked_items); //funkce vklada predmet(y) do batohu postavy void pick_set_cursor(void); //nastavuje kurzor podle vlozeneho predmetu; void calc_fly(THE_TIMER *t); diff --git a/game/inv.c b/game/inv.c index e33e0ae..afbe09e 100644 --- a/game/inv.c +++ b/game/inv.c @@ -432,7 +432,7 @@ void draw_placed_items_normal(int celx,int cely,int sect,int side) } } -int count_items_total(short *place) +int count_items_total(const short *place) { int c=0; @@ -441,7 +441,7 @@ int count_items_total(short *place) return c; } -int count_items_visible(short *place) +int count_items_visible(const short *place) { int c=0; @@ -455,7 +455,7 @@ int count_items_visible(short *place) } -int count_items_inside(short *place) +int count_items_inside(const short *place) { int c=1; @@ -492,30 +492,37 @@ static char ValidateSector(word sector, void *_) return 0; } -void push_item(int sect,int pos,short *picked_item) +void push_to_destroyed_items(const short *picked_items) { + int new_count = count_items_total(picked_items); + if (new_count == 0) return; + int cur_destroyed = count_items_total(destroyed_items); + short *nw = NewArr(short, new_count+cur_destroyed+1); + for (int i = 0; i < new_count; ++i) { + nw[i] = abs(picked_items[i]); + } + for (int i = 0; i < cur_destroyed; ++i) { + nw[new_count+i] = destroyed_items[i]; + } + nw[new_count+cur_destroyed] = 0; + free(destroyed_items); + destroyed_items = nw; +} + +void push_item(int sect,int pos,const short *picked_item) { int bc; int pc; int tc; short *p; + char s = map_sectors[sect].sector_type; + - if (map_sectors[sect].sector_type==S_DIRA || ISTELEPORTSECT(sect)) + if (s==S_DIRA || ISTELEPORTSECT(sect) || s == S_SCHODY) sect=map_sectors[sect].sector_tag; - if (sect==0 || map_sectors[sect].sector_type==S_VODA) - { - if (game_extras & EX_RECOVER_DESTROYED_ITEMS) - { - labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,ValidateSector,NULL, NULL); - push_item(lastsector,viewdir,picked_item); - return; - } - else - { - free(picked_item); - picked_item=NULL; - return; - } - } + if (sect==0 || s==S_VODA || s == S_LAVA || s == S_SSMRT) { + push_to_destroyed_items(picked_item); + return; + } sect=(sect<<2)+pos; bc=count_items_total(map_items[sect]); pc=count_items_total(picked_item); @@ -682,7 +689,7 @@ char pick_item_(int id,int xa,int ya,int xr,int yr) idd=(id+viewdir)&0x3; if (picked_item!=NULL) { - if (map_sectors[sect].sector_type==S_DIRA) + if (map_sectors[sect].sector_type==S_DIRA) { throw_fly(xa,ya,0); letici_veci->speed=0; diff --git a/game/realgame.c b/game/realgame.c index 80fd10c..e946bd5 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -62,7 +62,8 @@ TSTENA *map_sides; TSECTOR *map_sectors; TVYKLENEK *map_vyk; //mapa vyklenku word vyk_max; //pocet vyklenku v mape -short **map_items; +short **map_items = 0; +short *destroyed_items = 0;; char *flag_map; TMAP_EDIT_INFO *map_coord; TSTR_LIST level_texts;