From e646db35475f60d03d7166023e33339afb35b766 Mon Sep 17 00:00:00 2001 From: EmilyV99 Date: Wed, 16 Aug 2023 14:04:22 -0400 Subject: [PATCH] fix: more subscreen fixes --- src/items.cpp | 3 +- src/new_subscr.cpp | 88 ++++++++++++++++++++++++---------------------- src/new_subscr.h | 8 ++--- src/subscr.cpp | 13 +++++-- src/zc/zc_sys.cpp | 20 ++++------- 5 files changed, 70 insertions(+), 62 deletions(-) diff --git a/src/items.cpp b/src/items.cpp index b7c3422f75..cd1f858a00 100644 --- a/src/items.cpp +++ b/src/items.cpp @@ -643,8 +643,9 @@ void dummyitem_animate(item* dummy, int32_t clk) void putitem3(BITMAP *dest,int32_t x,int32_t y,int32_t item_id, int32_t clk) { item temp((zfix)x,(zfix)y,(zfix)0,item_id,0,0,true); - temp.yofs=0; + temp.xofs=temp.yofs=0; temp.hide_hitbox = true; + temp.subscreenItem = true; dummyitem_animate(&temp, clk); temp.draw(dest); diff --git a/src/new_subscr.cpp b/src/new_subscr.cpp index 881426b061..579b6021b3 100644 --- a/src/new_subscr.cpp +++ b/src/new_subscr.cpp @@ -2103,7 +2103,7 @@ int32_t SW_ItemSlot::getDisplayItem() const } case itype_bowandarrow: case itype_arrow: - if(current_item_id(itype_bow)>-1 && current_item_id(itype_arrow)>-1) + if(current_item_id(itype_arrow,false)>-1) { family=itype_arrow; } @@ -2132,8 +2132,7 @@ int32_t SW_ItemSlot::getDisplayItem() const } case itype_sword: { - if(get_qr(qr_SELECTAWPN)) - family=itype_sword; + family=itype_sword; break; } //Super Special Cases for display @@ -2671,6 +2670,7 @@ void SW_Selector::draw(BITMAP* dest, int32_t xofs, int32_t yofs, SubscrPage& pag bool big_sel=flags&SUBSCR_SELECTOR_LARGE; item tempsel(0,0,0,(flags&SUBSCR_SELECTOR_USEB)?iSelectB:iSelectA,0,0,true); + tempsel.subscreenItem=true; tempsel.hide_hitbox = true; tempsel.yofs = 0; dummyitem_animate(&tempsel,subscr_item_clk); @@ -2685,13 +2685,15 @@ void SW_Selector::draw(BITMAP* dest, int32_t xofs, int32_t yofs, SubscrPage& pag if(oldsel) { sw = (tempsel.extend > 2 ? tempsel.txsz*16 : 16); - sh = (tempsel.extend > 2 ? tempsel.txsz*16 : 16); + sh = (tempsel.extend > 2 ? tempsel.tysz*16 : 16); sxofs = 0; syofs = 0; dw = (tempsel.extend > 2 ? tempsel.txsz*16 : 16); - dh = (tempsel.extend > 2 ? tempsel.txsz*16 : 16); + dh = (tempsel.extend > 2 ? tempsel.tysz*16 : 16); dxofs = (tempsel.extend > 2 ? (int)tempsel.xofs : 0); dyofs = (tempsel.extend > 2 ? (int)tempsel.yofs : 0); + if(replay_version_check(0,19) && tempsel.extend > 2) + sh = dh = tempsel.txsz*16; } else { @@ -2699,20 +2701,20 @@ void SW_Selector::draw(BITMAP* dest, int32_t xofs, int32_t yofs, SubscrPage& pag sh = (tempsel.extend > 2 ? tempsel.hit_height : 16); sxofs = (tempsel.extend > 2 ? tempsel.hxofs : 0); syofs = (tempsel.extend > 2 ? tempsel.hyofs : 0); - } - if(widg->getType() == widgITEMSLOT) - { - dw = ((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_WIDTH) ? tmpitm.hxsz : 16); - dh = ((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_HEIGHT) ? tmpitm.hysz : 16); - dxofs = widg->getX()+((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_X_OFFSET) ? tmpitm.hxofs : 0) + (tempsel.extend > 2 ? (int)tempsel.xofs : 0); - dyofs = widg->getY()+((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_Y_OFFSET) ? tmpitm.hyofs : 0) + (tempsel.extend > 2 ? (int)tempsel.yofs : 0); - } - else - { - dw = widg->getW(); - dh = widg->getH(); - dxofs = widg->getX()+widg->getXOffs(); - dyofs = widg->getY()+widg->getYOffs(); + if(widg->getType() == widgITEMSLOT) + { + dw = ((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_WIDTH) ? tmpitm.hxsz : 16); + dh = ((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_HEIGHT) ? tmpitm.hysz : 16); + dxofs = widg->getX()+((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_X_OFFSET) ? tmpitm.hxofs : 0) + (tempsel.extend > 2 ? (int)tempsel.xofs : 0); + dyofs = widg->getY()+((tmpitm.overrideFLAGS & itemdataOVERRIDE_HIT_Y_OFFSET) ? tmpitm.hyofs : 0) + (tempsel.extend > 2 ? (int)tempsel.yofs : 0); + } + else + { + dw = widg->getW(); + dh = widg->getH(); + dxofs = widg->getX()+widg->getXOffs(); + dyofs = widg->getY()+widg->getYOffs(); + } } BITMAP* tmpbmp = create_bitmap_ex(8,sw,sh); for(int32_t j=0; j<4; ++j) @@ -2721,14 +2723,14 @@ void SW_Selector::draw(BITMAP* dest, int32_t xofs, int32_t yofs, SubscrPage& pag tempsel.x=0; tempsel.y=0; tempsel.draw(tmpbmp); - tempsel.tile+=zc_max(itemsbuf[tempsel.id].frames,1); - int32_t tmpx = xofs+(big_sel?(j%2?8:-8):0); - int32_t tmpy = yofs+(big_sel?(j>1?8:-8):0); + int32_t tmpx = widg->x+xofs+(big_sel?(j%2?8:-8):0); + int32_t tmpy = widg->y+yofs+(big_sel?(j>1?8:-8):0); masked_stretch_blit(tmpbmp, dest, vbound(sxofs, 0, sw), vbound(syofs, 0, sh), sw-vbound(sxofs, 0, sw), sh-vbound(syofs, 0, sh), tmpx+dxofs, tmpy+dyofs, dw, dh); if(!big_sel) break; + tempsel.tile+=zc_max(itemsbuf[tempsel.id].frames,1); } destroy_bitmap(tmpbmp); tempsel.unget_UID(); @@ -3418,7 +3420,7 @@ SubscrWidget* SubscrWidget::newType(byte ty) void SubscrPage::move_cursor(int dir, bool item_only) { // verify startpos - if(cursor_pos < 0 || cursor_pos >= 0xFF) + if(cursor_pos == 0xFF) cursor_pos = 0; auto& objects = contents; @@ -3508,7 +3510,7 @@ void SubscrPage::move_cursor(int dir, bool item_only) } } } -int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word fp3, bool equip_only, bool item_only) +int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word fp3, bool equip_only, bool item_only, bool stay_on_page) { //what will be returned when all else fails. //don't return the forbiddenpos... no matter what -DD @@ -3523,8 +3525,6 @@ int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word failpos = 0xFF; else failpos = startp; - auto& objects = contents; - item_only = item_only || !get_qr(qr_FREEFORM_SUBSCREEN_CURSOR); bool verify = dir==SEL_VERIFY_RIGHT || dir==SEL_VERIFY_LEFT; @@ -3534,7 +3534,7 @@ int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word item_only = !get_qr(qr_NO_BUTTON_VERIFY); if(start_empty && !item_only) return startp; //empty is valid - if(!start_empty && startp != fp && startp != fp2 && startp != fp3) + if(startp != fp && startp != fp2 && startp != fp3) if(SubscrWidget* widg = get_widg_pos(startp>>8,item_only)) if(widg->getType() == widgITEMSLOT && !(widg->flags&SUBSCR_CURITM_NONEQP) @@ -3544,7 +3544,8 @@ int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word } int32_t p=-1; - int32_t curpos = startp>>8; + byte curpos = startp>>8; + word cp2 = (curpos<<8)|index; //curpos is the index for this page, cp2 includes the page index int32_t firstValidPos=-1, firstValidEquipPos=-1; for(int32_t i=0; i < contents.size(); ++i) @@ -3579,16 +3580,18 @@ int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word //remember we've been here std::set oldPositions; - oldPositions.insert(curpos); + oldPositions.insert(cp2); //1. Perform any shifts required by the above //2. If that's not possible, go to position 1 and reset the b weapon. //2a. -if we arrive at a position we've already visited, give up and stay there //3. Get the weapon at the new slot //4. If it's not possible, go to step 1. - SubscrWidget* widg = contents[p]; + SubscrPage const* pg = this; + SubscrWidget const* widg = contents[p]; for(;;) { + //stay_on_page currently unused; nothing changes the current pg in a cycle yet. //shift switch(dir) { @@ -3610,33 +3613,34 @@ int32_t SubscrPage::movepos_legacy(int dir, word startp, word fp, word fp2, word curpos = widg->pos_up; break; } - + cp2 = (curpos<<8)|pg->index; //find our new position - widg = get_widg_pos(curpos,true); + widg = pg->get_widg_pos(curpos,true); if(!widg) return failpos; //if we've already been here, give up - if(oldPositions.find(curpos) != oldPositions.end()) + if(oldPositions.find(cp2) != oldPositions.end()) return failpos; //else, remember we've been here - oldPositions.insert(curpos); + oldPositions.insert(cp2); //Valid stop point? - if(widg->flags & SUBSCRFLAG_SELECTABLE) - if(curpos != fp && curpos != fp2 && curpos != fp3) - if(!equip_only || widg->getType()!=widgITEMSLOT || !(widg->flags & SUBSCR_CURITM_NONEQP)) - if(!item_only || widg->getItemVal()>-1) - return (curpos<<8)|index; + if((!stay_on_page||(cp2&0xFF)==index) + && (widg->flags & SUBSCRFLAG_SELECTABLE) + && cp2 != fp && cp2 != fp2 && cp2 != fp3 + && (!equip_only || widg->getType()!=widgITEMSLOT || !(widg->flags & SUBSCR_CURITM_NONEQP)) + && (!item_only || widg->getItemVal()>-1)) + return cp2; } } void SubscrPage::move_legacy(int dir, bool equip_only, bool item_only) { - cursor_pos = movepos_legacy(dir,(cursor_pos<<8)|index,255,255,255,equip_only,item_only); + cursor_pos = movepos_legacy(dir,(cursor_pos<<8)|index,255,255,255,equip_only,item_only,true)>>8; } -SubscrWidget* SubscrPage::get_widg_pos(byte pos, bool item_only) +SubscrWidget* SubscrPage::get_widg_pos(byte pos, bool item_only) const { for(size_t q = 0; q < contents.size(); ++q) { @@ -3657,7 +3661,7 @@ int32_t SubscrPage::get_item_pos(byte pos, bool item_only) return w->getItemVal(); return -1; } -SubscrWidget* SubscrPage::get_sel_widg() +SubscrWidget* SubscrPage::get_sel_widg() const { return get_widg_pos(cursor_pos,false); } diff --git a/src/new_subscr.h b/src/new_subscr.h index b42e093121..6785d84f33 100644 --- a/src/new_subscr.h +++ b/src/new_subscr.h @@ -814,13 +814,13 @@ struct SW_SelectedText : public SubscrWidget struct SubscrPage { std::vector contents; - int32_t cursor_pos, init_cursor_pos; + byte cursor_pos, init_cursor_pos; void move_cursor(int dir, bool item_only = false); - int32_t movepos_legacy(int dir, word startp, word fp = 255, word fp2 = 255, word fp3 = 255, bool equip_only=true, bool item_only=true); + int32_t movepos_legacy(int dir, word startp, word fp = 255, word fp2 = 255, word fp3 = 255, bool equip_only=true, bool item_only=true, bool stay_on_page = false); void move_legacy(int dir, bool equip_only=true, bool item_only=true); - SubscrWidget* get_widg_pos(byte pos, bool item_only); - SubscrWidget* get_sel_widg(); + SubscrWidget* get_widg_pos(byte pos, bool item_only) const; + SubscrWidget* get_sel_widg() const; int32_t get_item_pos(byte pos, bool item_only = true); int32_t get_sel_item(bool display = false); int32_t get_pos_of_item(int32_t itemid); diff --git a/src/subscr.cpp b/src/subscr.cpp index 26019ff68a..b037d3b944 100644 --- a/src/subscr.cpp +++ b/src/subscr.cpp @@ -3782,7 +3782,7 @@ void update_subscreens(int32_t dmap) ++j; } - new_subscreen_active=&new_subscreen[j-1]; + auto next_active = &new_subscreen[j-1]; index=DMaps[dmap].passive_subscreen; @@ -3796,7 +3796,16 @@ void update_subscreens(int32_t dmap) ++j; } - new_subscreen_passive=&new_subscreen[j-1]; + auto next_passive = &new_subscreen[j-1]; + + if(get_qr(qr_OLD_SUBSCR) && new_subscreen_active) + { + next_active->curpage = new_subscreen_active->curpage; + next_active->cur_page().cursor_pos = new_subscreen_active->cur_page().cursor_pos; + } + + new_subscreen_passive = next_passive; + new_subscreen_active = next_active; } void sso_bounding_box(BITMAP *bmp, SubscrWidget* widg, int32_t color) diff --git a/src/zc/zc_sys.cpp b/src/zc/zc_sys.cpp index 581fa88d89..bf4619993e 100644 --- a/src/zc/zc_sys.cpp +++ b/src/zc/zc_sys.cpp @@ -2280,13 +2280,14 @@ void flushItemCache(bool justcost) // This is used often, so it should be as direct as possible. int32_t _c_item_id_internal(int32_t itemtype, bool checkmagic, bool jinx_check) { - bool use_cost_cache = true;//replay_version_check(19); + bool use_cost_cache = replay_version_check(19); if(jinx_check) { if(!(HeroSwordClk() || HeroItemClk())) jinx_check = false; //not jinxed } - if (itemtype != itype_ring && !jinx_check) // Rings must always be checked, as must jinx checks... + if(itemtype == itype_ring) checkmagic = true; + if (!jinx_check) { auto& cache = checkmagic && use_cost_cache ? itemcache_cost : itemcache; auto res = cache.find(itemtype); @@ -2302,19 +2303,13 @@ int32_t _c_item_id_internal(int32_t itemtype, bool checkmagic, bool jinx_check) { if(game->get_item(i) && itemsbuf[i].family==itemtype && !item_disabled(i)) { - if((checkmagic || itemtype == itype_ring) && itemtype != itype_magicring) - { - //printf("Checkmagic for %d: %d (%d %d)\n",i,checkmagiccost(i),itemsbuf[i].magic*game->get_magicdrainrate(),game->get_magic()); + if(checkmagic && itemtype != itype_magicring) if(!checkmagiccost(i)) - { - if ( !get_qr(qr_NEVERDISABLEAMMOONSUBSCREEN) ) continue; //don't make items with a magic cost vanish!! -Z - } - } + if ( !get_qr(qr_NEVERDISABLEAMMOONSUBSCREEN) ) + continue; //don't make items with a magic cost vanish!! -Z if(jinx_check && (usesSwordJinx(i) ? HeroSwordClk() : HeroItemClk())) - { if(!(itemsbuf[i].flags & ITEM_JINX_IMMUNE)) continue; - } if(itemsbuf[i].fam_type >= highestlevel) { @@ -2329,9 +2324,7 @@ int32_t _c_item_id_internal(int32_t itemtype, bool checkmagic, bool jinx_check) if (use_cost_cache) { if (!checkmagic) - { itemcache[itemtype] = result; - } if (checkmagic || result < 0 || checkmagiccost(result)) itemcache_cost[itemtype] = result; } @@ -2361,6 +2354,7 @@ int32_t current_item_id(int32_t itemtype, bool checkmagic, bool jinx_check) } return ret; } + int32_t current_item_power(int32_t itemtype) { int32_t result = current_item_id(itemtype,true);