diff --git a/Crawler/CharacterAbilityPreviewComponent.h b/Crawler/CharacterAbilityPreviewComponent.h index df4bad92..1e5ae998 100644 --- a/Crawler/CharacterAbilityPreviewComponent.h +++ b/Crawler/CharacterAbilityPreviewComponent.h @@ -54,16 +54,16 @@ protected: virtual void inline Update(Crawler*game)override{ MenuLabel::Update(game); } - virtual void inline DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuLabel::DrawDecal(window,parentPos,focused); - vi2d iconPos=parentPos+rect.pos+vi2d{5,5}; + virtual void inline DrawDecal(ViewPort&window,bool focused)override{ + MenuLabel::DrawDecal(window,focused); + vi2d iconPos=rect.pos+vi2d{5,5}; vi2d textPos=iconPos; float textWidth=game->GetTextSizeProp(ability->input->GetDisplayName()).x*0.5f+4; float boxWidth=rect.size.y-4; //No, the y is not a typo. It's a square, we use the y to determine the x. - window.DrawRectDecal(parentPos+rect.pos+vi2d{2,2},vi2d{int(rect.size.y)-4,int(rect.size.y)-4}); + window.DrawRectDecal(rect.pos+vi2d{2,2},vi2d{int(rect.size.y)-4,int(rect.size.y)-4}); window.DrawDecal(iconPos,GFX[ability->icon].Decal()); vi2d descriptionPos=iconPos+vi2d{int(rect.size.y)-2,-1}; diff --git a/Crawler/CharacterMenuWindow.cpp b/Crawler/CharacterMenuWindow.cpp index b44b5015..74cc75b0 100644 --- a/Crawler/CharacterMenuWindow.cpp +++ b/Crawler/CharacterMenuWindow.cpp @@ -53,10 +53,10 @@ INCLUDE_GFX void Menu::InitializeCharacterMenuWindow(){ static bool equipmentWindowOpened=false; - vf2d windowSize=game->GetScreenSize()-vf2d{52,0}; + vf2d windowSize=game->GetScreenSize()-vf2d{52,52}; Menu*characterMenuWindow=CreateMenu(CHARACTER_MENU,CENTERED,windowSize); - characterMenuWindow->ADD("Character Label",MenuLabel)({{0,2},{float(windowSize.x)-1,24}},"Character",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END; + characterMenuWindow->ADD("Character Label",MenuLabel)({{0,-4},{float(windowSize.x)-1,24}},"Character",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END; characterMenuWindow->ADD("Equip Slot Outline",MenuComponent)({{0,28},{120,windowSize.y-48}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; characterMenuWindow->ADD("Character Rotating Display",CharacterRotatingDisplay)({{135,28},{90,windowSize.y-48}},GFX[classutils::GetClassInfo(game->GetPlayer()->GetClassName()).classFullImgName].Decal())END; @@ -71,13 +71,13 @@ void Menu::InitializeCharacterMenuWindow(){ }; - characterMenuWindow->ADD("Equip Selection Outline",MenuComponent)({{123,28},{120,windowSize.y-48}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END + characterMenuWindow->ADD("Equip Selection Outline",MenuComponent)({{123,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END ->Enable(false); - characterMenuWindow->ADD("Equip List",ScrollableWindowComponent)({{123,28},{120,windowSize.y-48-24}})DEPTH -1 END + characterMenuWindow->ADD("Equip List",ScrollableWindowComponent)({{123,28},{120,windowSize.y-37-24}})DEPTH -1 END ->Enable(false); - characterMenuWindow->ADD("Equip Selection Bottom Outline",MenuComponent)({{123,28+(windowSize.y-48-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END + characterMenuWindow->ADD("Equip Selection Bottom Outline",MenuComponent)({{123,28+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END ->Enable(false); - auto equipSelectionSelectButton=characterMenuWindow->ADD("Equip Selection Select Button",MenuComponent)({{123+12,28+(windowSize.y-48-24)+6},{96,12}},"Select", + auto equipSelectionSelectButton=characterMenuWindow->ADD("Equip Selection Select Button",MenuComponent)({{123+12,28+(windowSize.y-37-24)+6},{96,12}},"Select", [](MenuFuncData data){ Component(data.component->parentMenu,"Equip Selection Outline")->Enable(false); Component(data.component->parentMenu,"Equip List")->Enable(false); @@ -218,7 +218,7 @@ void Menu::InitializeCharacterMenuWindow(){ Menu::AddEquipStatListener(equipmentSlot); } - characterMenuWindow->ADD("Stat Display Outline",MenuComponent)({{245,28},{62,windowSize.y-48}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; + characterMenuWindow->ADD("Stat Display Outline",MenuComponent)({{245,28},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; int yOffset=0; for(ItemAttribute attribute:displayAttrs){ @@ -229,12 +229,12 @@ void Menu::InitializeCharacterMenuWindow(){ yOffset+=20; } - characterMenuWindow->ADD("Back button",MenuComponent)({{windowSize.x/2-64,windowSize.y-16},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END; + characterMenuWindow->ADD("Back button",MenuComponent)({{windowSize.x/2-64,windowSize.y},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END; auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuLabel)({{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; - auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuLabel)({{0,40},{120,windowSize.y-60}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; + auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuLabel)({{0,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; auto itemEquipNameDisplay=characterMenuWindow->ADD("Item Equip Name",MenuLabel)({{123,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; - auto itemEquipDescriptionDisplay=characterMenuWindow->ADD("Item Equip Description",MenuLabel)({{123,40},{120,windowSize.y-60}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; + auto itemEquipDescriptionDisplay=characterMenuWindow->ADD("Item Equip Description",MenuLabel)({{123,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; itemNameDisplay->Enable(false); itemDescriptionDisplay->Enable(false); diff --git a/Crawler/CharacterRotatingDisplay.h b/Crawler/CharacterRotatingDisplay.h index 44e5c2ec..b78aeed1 100644 --- a/Crawler/CharacterRotatingDisplay.h +++ b/Crawler/CharacterRotatingDisplay.h @@ -62,7 +62,7 @@ protected: timer-=2*PI; } } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ window.DrawWarpedDecal(icon,std::array{ rect.pos+vf2d{abs(sin(timer)),sin(float(timer+PI))}*vf2d{rotatingFactor,perspectiveFactor}, rect.pos+vf2d{0,rect.size.y}+vf2d{abs(sin(timer)),sin(timer)}*vf2d{rotatingFactor,perspectiveFactor}, diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 27880b8a..8ccd2c0a 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -215,7 +215,6 @@ bool Crawler::OnUserCreate(){ } bool Crawler::OnUserUpdate(float fElapsedTime){ - fElapsedTime=std::clamp(fElapsedTime,0.f,1/30.f); //HACK fix. We can't have a negative time. Although using a more precise system clock should make this never occur. Also make sure if the game is too slow we advance by only 1/30th of a second. levelTime+=fElapsedTime; if(!GamePaused()){ GameState::STATE->OnUserUpdate(this); diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h index 54c9c159..f894a0f0 100644 --- a/Crawler/DEFINES.h +++ b/Crawler/DEFINES.h @@ -54,6 +54,7 @@ All rights reserved. #define INCLUDE_ITEM_CATEGORIES extern safemap>ITEM_CATEGORIES; #define DO_NOTHING [](MenuFuncData data){return true;} #define INCLUDE_LEVEL_NAMES extern safemapLEVEL_NAMES; +#define INCLUDE_WINDOW_SIZE extern vi2d WINDOW_SIZE; #define INCLUDE_CENTERED extern const vf2d Menu::CENTERED; diff --git a/Crawler/InventoryConsumableWindow.cpp b/Crawler/InventoryConsumableWindow.cpp index 60364368..b963b8cc 100644 --- a/Crawler/InventoryConsumableWindow.cpp +++ b/Crawler/InventoryConsumableWindow.cpp @@ -61,7 +61,8 @@ void Menu::InitializeConsumableInventoryWindow(){ data.game->ClearLoadoutItem(data.menu.I(A::LOADOUT_SLOT)); for(MenuComponent*component:data.parentComponent->GetComponents()){ //HACK ALERT! If we are accessing a parent component, it's because we are dealing with a scrolling window component, which has sub-components. So this should be a safe cast to make. if(component->GetName().starts_with("item")){ - MenuItemButton*button2=(MenuItemButton*)component;//HACK ALERT! This is probably an item since we populated item lists using this name for the components. So we assume these are MenuItemButton classes. + MenuItemButton*button2=dynamic_cast(component);//HACK ALERT! This is probably an item since we populated item lists using this name for the components. So we assume these are MenuItemButton classes. + if(button2==nullptr)continue; if(button2==button){ if(button2->selected!=-1){ data.game->ClearLoadoutItem(button2->selected); diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp index 87364fc9..c20e9418 100644 --- a/Crawler/Menu.cpp +++ b/Crawler/Menu.cpp @@ -69,13 +69,13 @@ std::string Menu::lastRegisteredComponent; INCLUDE_game INCLUDE_GFX -extern vi2d WINDOW_SIZE; +INCLUDE_WINDOW_SIZE using A=Attribute; Menu::Menu(vf2d pos,vf2d size) :pos(pos==CENTERED?WINDOW_SIZE/2-size/2:vi2d{pos}),size(size){ - this->window=ViewPort::rectViewPort({0,0},size,this->pos); + this->window=ViewPort::rectViewPort({-24,-24},this->size+vi2d{48,48},this->pos); } Menu::~Menu(){ @@ -202,11 +202,14 @@ void Menu::Update(Crawler*game){ itemHovered=true; selection.y=key; selection.x=index; + goto selected; } } index++; } } + selected: + int a; } if(itemHovered&&draggingComponent==nullptr&&selection!=vi2d{-1,-1}&&(((!UsingMouseNavigation()&&(game->GetKey(ENTER).bHeld)||game->GetKey(SPACE).bHeld))||game->GetMouse(Mouse::LEFT).bHeld)){ @@ -305,11 +308,16 @@ void Menu::Draw(Crawler*game){ MenuComponent*selectedComponent=buttons[selection.y][selection.x]; vf2d drawOffset{}; if(selectedComponent->parentComponent!=nullptr){ - drawOffset+=selectedComponent->parentComponent->V(A::SCROLL_OFFSET); + ScrollableWindowComponent*scrollableComponent=dynamic_cast(selectedComponent->parentComponent); + if(scrollableComponent!=nullptr){ + drawOffset+=scrollableComponent->GetScrollAmount(); + } } - draggingComponent->DrawDecal(window,drawOffset+pos-offsetPos+selectedComponent->rect.pos+vi2d{1,-4},this==Menu::stack.back()); + draggingComponent->V(A::DRAW_OFFSET)=drawOffset+pos-offsetPos+selectedComponent->rect.pos+vi2d{1,-4}; + draggingComponent->DrawDecal(window,this==Menu::stack.back()); }else{ - draggingComponent->DrawDecal(window,-offsetPos+game->GetMousePos(),this==Menu::stack.back()); + draggingComponent->V(A::DRAW_OFFSET)-offsetPos+game->GetMousePos(); + draggingComponent->DrawDecal(window,this==Menu::stack.back()); } } }; @@ -435,20 +443,7 @@ void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){ selection={0,firstInd}; } } - }else{//Mouse click. - selection={-1,-1}; - for(auto&[key,value]:buttons){ - int index=0; - for(auto&button:value){ - if(!button->disabled){ - if(geom2d::overlaps(geom2d::rect{button->rect.pos+menuPos,button->rect.size},game->GetMousePos())){ - selection={index,key}; - break; - } - } - index++; - } - } + }else{ buttonHoldTime=0; } } diff --git a/Crawler/MenuAnimatedIconButton.h b/Crawler/MenuAnimatedIconButton.h index 2de30e1e..7d5347c7 100644 --- a/Crawler/MenuAnimatedIconButton.h +++ b/Crawler/MenuAnimatedIconButton.h @@ -55,10 +55,10 @@ protected: MenuIconButton::Update(game); animationTime+=game->GetElapsedTime(); } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuComponent::DrawDecal(window,parentPos,focused); //INTENTIONAL! The way we draw animations is different from static images, we skip over MenuIconButton's draw! + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ + MenuComponent::DrawDecal(window,focused); //Skipping to MenuComponent's DrawDecal is INTENTIONAL! The way we draw animations is different from static images, we skip over MenuIconButton's draw! Decal*spr=ANIMATION_DATA[animation].GetFrame(animationTime).GetSourceImage()->Decal(); geom2d::rectsprRect=ANIMATION_DATA[animation].GetFrame(animationTime).GetSourceRect(); - window.DrawPartialDecal(parentPos+rect.middle()-sprRect.size/2,spr,sprRect.pos,sprRect.size); + window.DrawPartialDecal(rect.middle()-sprRect.size/2,spr,sprRect.pos,sprRect.size); } }; \ No newline at end of file diff --git a/Crawler/MenuAnimatedIconToggleButton.h b/Crawler/MenuAnimatedIconToggleButton.h index 9739038d..8924d2bd 100644 --- a/Crawler/MenuAnimatedIconToggleButton.h +++ b/Crawler/MenuAnimatedIconToggleButton.h @@ -63,8 +63,8 @@ protected: hoverEffect="ThemeGlobal.HighlightTime"_F; //A hack that allows us to make it look like we have this selected. } } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuAnimatedIconButton::DrawDecal(window,parentPos,focused); + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ + MenuAnimatedIconButton::DrawDecal(window,focused); if(IsSelected()){ window.DrawRectDecal(rect.pos+vi2d{2,2},rect.size-vi2d{4,4},YELLOW); } diff --git a/Crawler/MenuComponent.cpp b/Crawler/MenuComponent.cpp index c368fe84..6f3fbd32 100644 --- a/Crawler/MenuComponent.cpp +++ b/Crawler/MenuComponent.cpp @@ -45,7 +45,7 @@ INCLUDE_game using A=Attribute; MenuComponent::MenuComponent(geom2d::rectrect,std::string label,MenuFunc onClick,ButtonAttr attributes) - :rect(rect),label(label),menuDest(MenuType::ENUM_END),onClick(onClick),hoverEffect(0),selectable(!(attributes&ButtonAttr::UNSELECTABLE)),selectableViaKeyboard(!(attributes&ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)),memoryLeakInfo(Menu::GetMemoryLeakReportInfo()){ + :rect(rect),originalPos(rect.pos),label(label),menuDest(MenuType::ENUM_END),onClick(onClick),hoverEffect(0),selectable(!(attributes&ButtonAttr::UNSELECTABLE)),selectableViaKeyboard(!(attributes&ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)),memoryLeakInfo(Menu::GetMemoryLeakReportInfo()){ Menu::unhandledComponents.push_back(this); } @@ -95,26 +95,26 @@ void MenuComponent::_Update(Crawler*game){ void MenuComponent::OnEquipStatsUpdate(){} -void MenuComponent::DrawDecal(ViewPort&window,vf2d parentPos,bool focused){ +void MenuComponent::DrawDecal(ViewPort&window,bool focused){ if(background){ - window.FillRectDecal(rect.pos+parentPos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F)); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET),rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F)); } if(selected&&selectionType==HIGHLIGHT){ - window.FillRectDecal(rect.pos+parentPos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),util::lerp(0.75f,1.0f,hoverEffect/"ThemeGlobal.HighlightTime"_F))); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET),rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),util::lerp(0.75f,1.0f,hoverEffect/"ThemeGlobal.HighlightTime"_F))); } if(border){ - window.FillRectDecal(rect.pos+parentPos,{rect.size.x+1,1}); - window.FillRectDecal(rect.pos+parentPos,{1,rect.size.y+1}); - window.FillRectDecal(rect.pos+parentPos+vf2d{rect.size.x-1+1,0},{1,rect.size.y+1}); - window.FillRectDecal(rect.pos+parentPos+vf2d{0,rect.size.y-1+1},{rect.size.x+1,1}); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET),{rect.size.x+1,1}); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET),{1,rect.size.y+1}); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET)+vf2d{rect.size.x-1+1,0},{1,rect.size.y+1}); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET)+vf2d{0,rect.size.y-1+1},{rect.size.x+1,1}); } if(showDefaultLabel){ - window.DrawStringPropDecal(rect.pos+parentPos+rect.size/2-vf2d(game->GetTextSizeProp(label))/2.f*labelScaling,label,WHITE,labelScaling); + window.DrawStringPropDecal(rect.pos+V(A::DRAW_OFFSET)+rect.size/2-vf2d(game->GetTextSizeProp(label))/2.f*labelScaling,label,WHITE,labelScaling); } if(selected){ switch(selectionType){ - case CROSSHAIR:drawutil::DrawCrosshairDecalViewPort(window,{parentPos+rect.pos,rect.size},0);break; - case INNER_BOX:window.DrawRectDecal(rect.pos+parentPos+vi2d{1,1},rect.size-vi2d{2,2});break; + case CROSSHAIR:drawutil::DrawCrosshairDecalViewPort(window,{rect.pos+V(A::DRAW_OFFSET),rect.size},0);break; + case INNER_BOX:window.DrawRectDecal(rect.pos+V(A::DRAW_OFFSET)+vi2d{1,1},rect.size-vi2d{2,2});break; case HIGHLIGHT:break;//Not used. default:ERR("Undefined selection type selected: "<rect; + vf2d originalPos; std::string label; bool border=true; bool draggable=false; @@ -96,7 +96,7 @@ protected: bool valid=true; //If set to false, this would cause the component to be removed. vf2d labelScaling={1,1}; virtual void Update(Crawler*game); - virtual void DrawDecal(ViewPort&window,vf2d parentPos,bool focused); + virtual void DrawDecal(ViewPort&window,bool focused); virtual bool GetHoverState(Crawler*game,MenuComponent*child); virtual void AfterCreate(); //Called after the creation of all menus finish. //CALL THIS FOR A PARENT to check a child's DrawDecal validity! diff --git a/Crawler/MenuIconButton.h b/Crawler/MenuIconButton.h index ce68af06..928b39f4 100644 --- a/Crawler/MenuIconButton.h +++ b/Crawler/MenuIconButton.h @@ -59,11 +59,11 @@ protected: virtual inline void Update(Crawler*game)override{ MenuComponent::Update(game); } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuComponent::DrawDecal(window,parentPos,focused); + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ + MenuComponent::DrawDecal(window,focused); if(icon!=nullptr){ vf2d iconScale=rect.size/24.f; - window.DrawDecal(parentPos+rect.middle()-icon->sprite->Size()*iconScale/2,icon,iconScale); + window.DrawDecal(rect.middle()-icon->sprite->Size()*iconScale/2,icon,iconScale); } } }; diff --git a/Crawler/MenuItemButton.h b/Crawler/MenuItemButton.h index a2cd41d6..1e7f1e96 100644 --- a/Crawler/MenuItemButton.h +++ b/Crawler/MenuItemButton.h @@ -133,10 +133,10 @@ protected: } } } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuIconButton::DrawDecal(window,parentPos,focused); + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ + MenuIconButton::DrawDecal(window,focused); if(selected!=-1){ - drawutil::DrawCrosshairDecalViewPort(window,{parentPos+rect.pos,rect.size},0); + drawutil::DrawCrosshairDecalViewPort(window,{rect.pos,rect.size},0); } if(valid){ int itemQuantity=Inventory::GetItemCount(invRef.at(inventoryIndex).Name()); //Normally we'd retrieve how many of this item we have from our inventory...However Monster Loot and Stage Loot inventories are special and hold their own inventory counts... @@ -146,7 +146,7 @@ protected: std::string quantityText="x"+std::to_string(itemQuantity); vf2d quantityTextScale=rect.size/48.f; vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale; - vf2d drawPos=parentPos+rect.pos+rect.size-textSize; + vf2d drawPos=rect.pos+rect.size-textSize; geom2d::rectboundingBox={drawPos,textSize}; window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x); } diff --git a/Crawler/MenuItemItemButton.h b/Crawler/MenuItemItemButton.h index 73670165..16186189 100644 --- a/Crawler/MenuItemItemButton.h +++ b/Crawler/MenuItemItemButton.h @@ -131,13 +131,13 @@ protected: } } } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuIconButton::DrawDecal(window,parentPos,focused); + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ + MenuIconButton::DrawDecal(window,focused); if(valid&&!hideQty){ std::string quantityText="x"+std::to_string(itemRef.get().Amt()); vf2d quantityTextScale=rect.size/48.f; vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale; - vf2d drawPos=parentPos+rect.pos+rect.size-textSize; + vf2d drawPos=rect.pos+rect.size-textSize; geom2d::rectboundingBox={drawPos,textSize}; window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x); } diff --git a/Crawler/MenuLabel.h b/Crawler/MenuLabel.h index ded2c3f2..83e10567 100644 --- a/Crawler/MenuLabel.h +++ b/Crawler/MenuLabel.h @@ -64,12 +64,12 @@ protected: virtual void inline Update(Crawler*game)override{ MenuComponent::Update(game); } - virtual void inline DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuComponent::DrawDecal(window,parentPos,focused); + virtual void inline DrawDecal(ViewPort&window,bool focused)override{ + MenuComponent::DrawDecal(window,focused); std::string wrappedText=util::WrapText(game,label,int(rect.size.x),true,{float(scale),float(scale)}); - vf2d drawPos=parentPos+rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*float(scale)/2; //Assume centered. + vf2d drawPos=rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*float(scale)/2; //Assume centered. if(!centered){ - drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}+parentPos; //We should at least vertically align here. + drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}; //We should at least vertically align here. } if(shadow){ window.DrawShadowStringPropDecal(drawPos,wrappedText,WHITE,BLACK,{float(scale),float(scale)}); diff --git a/Crawler/MonsterAttribute.h b/Crawler/MonsterAttribute.h index cedc151b..99429c96 100644 --- a/Crawler/MonsterAttribute.h +++ b/Crawler/MonsterAttribute.h @@ -65,11 +65,11 @@ enum class Attribute{ JUMP_TOWARDS_PLAYER, HITS_UNTIL_DEATH, //When this is set, it is reduced by 1 each time the monster is hit. INDEXED_THEME, - SCROLL_OFFSET, CLASS_SELECTION, //A class name that represents what the menu's class is. LOADOUT_SLOT, //Which loadout slot we are selecting an item for. ALLOW_DRAGGING, //Whether or not to allow inventory dragging. EQUIP_TYPE, BASE_TEXT, CATEGORY_NAME, + DRAW_OFFSET, }; \ No newline at end of file diff --git a/Crawler/PopupMenuLabel.h b/Crawler/PopupMenuLabel.h index fab7846c..1df3116c 100644 --- a/Crawler/PopupMenuLabel.h +++ b/Crawler/PopupMenuLabel.h @@ -57,21 +57,21 @@ protected: virtual void inline Update(Crawler*game)override{ MenuLabel::Update(game); } - virtual void inline DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ + virtual void inline DrawDecal(ViewPort&window,bool focused)override{ if(label.length()>0){ std::string wrappedText=util::WrapText(game,label,int(rect.size.x-1),true,scale); - vf2d drawPos=parentPos+rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*scale/2; //Assume centered. + vf2d drawPos=rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*scale/2; //Assume centered. if(!centered){ - drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}+parentPos; //We should at least vertically align here. + drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}; //We should at least vertically align here. } if(background){ - window.FillRectDecal(rect.pos+parentPos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F)); + window.FillRectDecal(rect.pos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F)); } if(border){ - window.DrawRectDecal(rect.pos+parentPos,rect.size); + window.DrawRectDecal(rect.pos,rect.size); } if(showDefaultLabel){ - window.DrawStringPropDecal(rect.pos+parentPos+rect.size/2-game->GetTextSizeProp(label)/2,label); + window.DrawStringPropDecal(rect.pos+rect.size/2-game->GetTextSizeProp(label)/2,label); } if(shadow){ window.DrawShadowStringPropDecal(drawPos,wrappedText,WHITE,BLACK,scale); diff --git a/Crawler/ScrollableWindowComponent.h b/Crawler/ScrollableWindowComponent.h index f304f473..6d9fd1f0 100644 --- a/Crawler/ScrollableWindowComponent.h +++ b/Crawler/ScrollableWindowComponent.h @@ -54,9 +54,10 @@ protected: float scrollBarTop=0; bool scrollBarSelected=false; float scrollBarHoverTime=0; + vf2d scrollOffset; protected: inline bool OnScreen(MenuComponent*component){ - return geom2d::overlaps(geom2d::rect{{},rect.size},geom2d::rect{component->rect.pos+V(A::SCROLL_OFFSET)+vf2d{2,2},component->rect.size-vf2d{2,2}}); + return geom2d::overlaps(geom2d::rect{{},rect.size},geom2d::rect{component->rect.pos+vf2d{2,2},component->rect.size-vf2d{2,2}}); } public: inline ScrollableWindowComponent(geom2d::rectrect,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) @@ -93,11 +94,20 @@ public: Menu::menus[button->parentMenu]->RecalculateComponentCount(); delete button; } + virtual inline void SetScrollAmount(vf2d scrollOffset){ + this->scrollOffset=scrollOffset; + for(MenuComponent*component:components){ + component->rect.pos=component->originalPos+scrollOffset; + } + } + virtual inline vf2d GetScrollAmount(){ + return scrollOffset; + } protected: virtual inline void AfterCreate()override{ //Let's use the internal name of this component to add unique names for sub-components. - upButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+vf2d{rect.size.x-12,0}).str()+"_"+vf2d(12,12).str(),MenuComponent)({rect.pos+vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH -1 END; - downButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+rect.size-vf2d{12,12}).str()+"_"+vf2d(12,12).str(),MenuComponent)({rect.pos+rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH -1 END; + upButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+vf2d{rect.size.x-12,0}).str()+"_"+vf2d(12,12).str(),MenuComponent)({rect.pos+vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){SetScrollAmount(GetScrollAmount()+vf2d{0,"ThemeGlobal.MenuButtonScrollSpeed"_F});return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH -1 END; + downButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+rect.size-vf2d{12,12}).str()+"_"+vf2d(12,12).str(),MenuComponent)({rect.pos+rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){SetScrollAmount(GetScrollAmount()-vf2d{0,"ThemeGlobal.MenuButtonScrollSpeed"_F});return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH -1 END; subWindow=ViewPort::rectViewPort({},rect.size,Menu::menus[parentMenu]->pos+rect.pos); if(upButton){upButton->Enable(!disabled);} if(downButton){downButton->Enable(!disabled);} @@ -132,7 +142,7 @@ protected: float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight); //The scroll amount moves centered on the position the mouse is at. float newScrollbarTop=(game->GetMousePos().y-windowAbsPos.y-12)-scrollBarHeight/2; - V(A::SCROLL_OFFSET).y=(-newScrollbarTop+1)/scrollBarScale; //Derived formula from the draw code. + SetScrollAmount({GetScrollAmount().x,(-newScrollbarTop+1)/scrollBarScale}); } }else{ scrollBarHoverTime=std::max(scrollBarHoverTime-game->GetElapsedTime(),0.f); @@ -140,16 +150,16 @@ protected: if(game->GetMouseWheel()!=0){ if(game->GetMouseWheel()>0){ - V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuScrollWheelSpeed"_I; + SetScrollAmount(GetScrollAmount()+vf2d{0,"ThemeGlobal.MenuScrollWheelSpeed"_F}); }else{ - V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuScrollWheelSpeed"_I; + SetScrollAmount(GetScrollAmount()-vf2d{0,"ThemeGlobal.MenuScrollWheelSpeed"_F}); } } if(bounds.size.y-rect.size.y>0){ - V(A::SCROLL_OFFSET).y=std::clamp(V(A::SCROLL_OFFSET).y,-(bounds.size.y-rect.size.y),0.f); + SetScrollAmount({GetScrollAmount().x,std::clamp(GetScrollAmount().y,-(bounds.size.y-rect.size.y),0.f)}); }else{ - V(A::SCROLL_OFFSET).y=0; + SetScrollAmount({GetScrollAmount().x,0}); } std::sort(components.begin(),components.end(),[](MenuComponent*c1,MenuComponent*c2){return c1->depth>c2->depth;}); @@ -172,7 +182,7 @@ protected: if(totalContentHeight==0)totalContentHeight=1; float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight); scrollBarHeight=std::min(spaceBetweenTopAndBottomArrows,viewHeight*scrollBarScale-1); - scrollBarTop=-V(A::SCROLL_OFFSET).y*scrollBarScale+1; + scrollBarTop=-GetScrollAmount().y*scrollBarScale+1; float focusedWindowColorMult=(focused?1:"ThemeGlobal.MenuUnfocusedColorMult"_F); @@ -180,18 +190,18 @@ protected: window.DrawRectDecal(rect.pos+parentPos+vf2d{rect.size.x-11.75f,scrollBarTop+12},{12,scrollBarHeight},WHITE*focusedWindowColorMult); } - virtual inline void DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ - MenuComponent::DrawDecal(window,parentPos,focused); + virtual inline void DrawDecal(ViewPort&window,bool focused)override{ + MenuComponent::DrawDecal(window,focused); if(border){ window.DrawRectDecal(rect.pos,rect.size); } for(MenuComponent*component:components){ - component->_DrawDecal(subWindow,V(A::SCROLL_OFFSET),focused); + component->_DrawDecal(subWindow,focused); } DrawScrollbar(window,{},focused); } virtual bool GetHoverState(Crawler*game,MenuComponent*child)override{ - return geom2d::overlaps(geom2d::rect{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos+V(A::SCROLL_OFFSET),child->rect.size},game->GetMousePos()); + return geom2d::overlaps(geom2d::rect{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos,child->rect.size},game->GetMousePos()); } //Calculates the bounds of all components. geom2d::rect inline CalculateBounds(){ @@ -255,8 +265,7 @@ public: } virtual inline bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton)override{ //Set the offset so the center is highlighted by this button. - V(A::SCROLL_OFFSET).y=-(disabledButton->rect.pos.y-disabledButton->rect.size.y/2); - V(A::SCROLL_OFFSET).y+=rect.size.y/2; + SetScrollAmount(vf2d{GetScrollAmount().x,-disabledButton->rect.pos.y+disabledButton->rect.size.y}); return true; }; virtual void Cleanup()override{} diff --git a/Crawler/SpawnEncounterLabel.h b/Crawler/SpawnEncounterLabel.h index e47e52ec..6252f741 100644 --- a/Crawler/SpawnEncounterLabel.h +++ b/Crawler/SpawnEncounterLabel.h @@ -64,16 +64,16 @@ protected: MenuComponent::Update(game); anim.UpdateState(state,game->GetElapsedTime()); } - virtual void inline DrawDecal(ViewPort&window,vf2d parentPos,bool focused)override{ + virtual void inline DrawDecal(ViewPort&window,bool focused)override{ const geom2d::rect&imgRect=anim.GetFrame(state).GetSourceRect(); vf2d imgSize=vf2d{rect.size.y,rect.size.y}; vf2d imgScale=imgSize/vf2d{imgRect.size}; - window.DrawPartialDecal(parentPos+rect.pos,imgSize,anim.GetFrame(state).GetSourceImage()->Decal(),imgRect.pos,imgRect.size); + window.DrawPartialDecal(rect.pos,imgSize,anim.GetFrame(state).GetSourceImage()->Decal(),imgRect.pos,imgRect.size); float verticalAlignYOffset=(rect.size.y-8)/2; std::string monsterName=MONSTER_DATA.at(monsterID).GetDisplayName(); vf2d monsterNameTextSize=game->GetTextSizeProp(monsterName); float textXSpaceAvailable=rect.size.x-imgSize.x-4-16/*12 for the scrollbar*/; float textXScaling=textXSpaceAvailable/monsterNameTextSize.x; - window.DrawShadowStringPropDecal(parentPos+rect.pos+vf2d{imgSize.x+4,verticalAlignYOffset},monsterName,WHITE,BLACK,{std::min(1.f,textXScaling),1}); + window.DrawShadowStringPropDecal(rect.pos+vf2d{imgSize.x+4,verticalAlignYOffset},monsterName,WHITE,BLACK,{std::min(1.f,textXScaling),1}); } }; \ No newline at end of file diff --git a/Crawler/Version.h b/Crawler/Version.h index f082a554..16191e27 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 3941 +#define VERSION_BUILD 3969 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/olcPixelGameEngine.h b/Crawler/olcPixelGameEngine.h index 2a78e100..49acf016 100644 --- a/Crawler/olcPixelGameEngine.h +++ b/Crawler/olcPixelGameEngine.h @@ -4328,7 +4328,8 @@ namespace olc m_tp1 = m_tp2; // Our time per frame coefficient - float fElapsedTime = elapsedTime.count(); + float actualElapsedTime = elapsedTime.count(); + float fElapsedTime = std::clamp(elapsedTime.count(),0.f,1/30.f); //HACK fix. We can't have a negative time. Although using a more precise system clock should make this never occur. Also make sure if the game is too slow we advance by only 1/30th of a second. fLastElapsed = fElapsedTime; fRunTime += fElapsedTime; @@ -4441,7 +4442,7 @@ namespace olc renderer->DisplayFrame(); // Update Title Bar - fFrameTimer += fElapsedTime; + fFrameTimer += actualElapsedTime; nFrameCount++; if (fFrameTimer >= 1.0f) { diff --git a/x64/Release/Crawler.exe b/x64/Release/Crawler.exe index dcbf24b7..bc4f2bee 100644 Binary files a/x64/Release/Crawler.exe and b/x64/Release/Crawler.exe differ