#include "Textbox.h" #include "olcUTIL_Geometry2D.h" #include "util.h" Textbox::Textbox(){}; void Textbox::Initialize(std::string text,vf2d pos,std::string headerText,Renderable*boxImg,vf2d maxSize,Audio*dialogSound,std::vectorresourceCost,float letterDisplayDelay) { if(GetCurrentString()!=text){ //Make sure this is actually a new textbox SetDefaults(); this->text=text; this->headerText=headerText; this->maxSize=maxSize; this->resourceCost=resourceCost; this->letterDisplayDelay=letterDisplayDelay; this->boxImg=boxImg; if(this->dialogSound!=nullptr){ this->dialogSound->Stop(soundHandle); this->dialogSound=nullptr; } if(dialogSound!=nullptr){ this->dialogSound=dialogSound; soundHandle=this->dialogSound->PlayCentered(1,audioVolume,true); } visible=true; } } void Textbox::SetDefaults(){ lastLetterTime=0; textboxMarker=-1; lastWordMarker=-1; lastWord=""; lastHeaderWordMarker=-1; lastHeaderWord=""; displayText=""; displayHeaderText=""; text=""; headerText=""; audioVolume=0; continueWordTimer=0; bPressed=false; } void Textbox::Update(PixelGameEngine*pge){ if(!visible){ if(dialogSound!=nullptr){ audioVolume=std::max(0.f,audioVolume-pge->GetElapsedTime()*2); dialogSound->SetVolume(soundHandle,audioVolume); } return; } lastLetterTime-=pge->GetElapsedTime(); continueWordTimer+=pge->GetElapsedTime(); if(lastLetterTime<=0){ if(textboxMarkermaxSize; if(boxImg!=nullptr){ maxSize-={26,0}; } if(pge->GetTextSizeProp(tempText).x>=maxSize.x){ displayText=displayText.substr(0,lastWordMarker); displayText+='\n'; displayText+=lastWord; } if(text[textboxMarker+1]==' '||text[textboxMarker+1]=='\n'){ lastWord=""; lastWordMarker=textboxMarker+2; } else { lastWord+=text[textboxMarker+1]; } displayText+=text[textboxMarker+1]; }; WrapText(tempText,text,displayText,lastWordMarker,lastWord); if(textboxMarkerSetVolume(soundHandle,audioVolume); audioFadeOutDelay=2; } }else{ if(dialogSound!=nullptr){ audioFadeOutDelay=std::max(0.f,audioFadeOutDelay-0.01f); if(audioFadeOutDelay<=0){ audioVolume=std::max(0.f,audioVolume-0.01f*2); dialogSound->SetVolume(soundHandle,audioVolume); } } bPressed=pge->GetMouse(0).bPressed||pge->GetMouse(1).bPressed; } maxSize.y=std::max(maxSize.y,float(pge->GetTextSizeProp(displayHeaderText).y+pge->GetTextSizeProp(displayText).y)); lastLetterTime=letterDisplayDelay; } } void Textbox::Draw(PixelGameEngine*pge,Resources&resources,std::vector>&IMAGES,int totalUsedMemory,int memoryLimit){ if(visible){ geom2d::rectboundingRect={pos-vf2d{3,3},maxSize+vf2d{6,6}}; if(resourceCost.size()>0){ boundingRect.size.x+=36; boundingRect.size.y=std::max(36.f,boundingRect.size.y); } if(boxImg!=nullptr){ boundingRect.size.x+=26; } if(boundingRect.bottom().start.y>=pge->ScreenHeight()){ boundingRect.pos-={0,boundingRect.bottom().start.y-pge->ScreenHeight()}; } if(boundingRect.right().start.x>=pge->ScreenWidth()){ boundingRect.pos-={boundingRect.right().start.x-pge->ScreenWidth(),0}; } if(boundingRect.top().start.y<0){ boundingRect.pos+={0,-boundingRect.top().start.y}; } if(boundingRect.left().start.x<0){ boundingRect.pos+={-boundingRect.left().start.x,0}; } geom2d::recttextboxRect=boundingRect; if(boxImg!=nullptr){ textboxRect.pos.x+=26; textboxRect.size.x-=50; } pge->FillRectDecal(boundingRect.pos,maxSize+vf2d{6,6},backCol); pge->DrawRectDecal(boundingRect.pos+vf2d{1,1},maxSize+vf2d{4,4},WHITE); if(boxImg!=nullptr){ pge->DrawDecal(boundingRect.pos+vf2d{3,3},IMAGES[MATRIX]->Decal(),{0.375,0.375},DARK_GREY); pge->DrawDecal(boundingRect.pos+vf2d{3,3},boxImg->Decal()); pge->DrawRectDecal(boundingRect.pos+vf2d{3,3},{24,24},YELLOW); } pge->DrawShadowStringPropDecal(textboxRect.pos+vf2d{3,3},displayHeaderText,{245, 218, 66}); pge->DrawShadowStringPropDecal(textboxRect.pos+vf2d{3.f,float(3+pge->GetTextSizeProp(displayHeaderText).y)},displayText,{220,220,220}); if(textboxMarker==int(text.length()-1)&&boxImg!=nullptr){ std::string continueText="Click to Continue"; pge->DrawShadowStringPropDecal(textboxRect.pos+textboxRect.size-vf2d(pge->GetTextSizeProp(continueText))*vf2d{0.6,1}-vf2d{5,-9},continueText,{255,255,255,uint8_t(abs(sin(2*continueWordTimer))*255)},{0,0,0,uint8_t(abs(sin(2*continueWordTimer))*255)},{0.6,1}); } if(resourceCost.size()>0){ geom2d::rectresourceBoxRect={textboxRect.pos+vf2d{6+maxSize.x,0},{36,42}}; pge->FillRectDecal(resourceBoxRect.pos,resourceBoxRect.size,backCol); pge->DrawRectDecal(resourceBoxRect.pos+vf2d{1,1},resourceBoxRect.size-vf2d{2,2},WHITE); vf2d contentPos=resourceBoxRect.pos+vf2d{3,3}; Pixel drawcol=GREY,shadowCol={66, 164, 245}; auto DrawResourceAmount=[&](int index,int cost,int resourceAmt){ drawcol=resourceAmt>=cost?GREY:RED; shadowCol=drawcol==GREY?VERY_DARK_BLUE:VERY_DARK_RED; vf2d textScale = {0.4,0.4}; std::string displayString = std::to_string(resourceAmt)+(resourceAmt<10?" ":"")+"/"; if(resourceAmtFillRectDecal(contentPos+vf2d{0,float(index*6)},vf2d{resourceBoxRect.size.x-6,6},{160,0,0,192}); } pge->DrawShadowStringDecal(contentPos+vf2d{12.f,float(index*6)+1},displayString,drawcol,shadowCol,textScale,0.6); pge->DrawShadowStringDecal(contentPos+vf2d{12.f+pge->GetTextSize(displayString).x*textScale.x+2,float(index*6)+1},std::to_string(cost),drawcol,shadowCol,{0.4,0.4},0.6); }; int index=0; int totalCost=0; if(util::GetHealthCost(resourceCost)!=-1){ DrawResourceAmount(index,util::GetHealthCost(resourceCost),resources.health); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::HEALTH_COLOR); totalCost+=util::GetHealthCost(resourceCost); index++; } if(util::GetAtkSpdCost(resourceCost)!=-1){ DrawResourceAmount(index,util::GetAtkSpdCost(resourceCost),resources.atkSpd); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::ATKSPD_COLOR); totalCost+=util::GetAtkSpdCost(resourceCost); index++; } if(util::GetMoveSpdCost(resourceCost)!=-1){ DrawResourceAmount(index,util::GetMoveSpdCost(resourceCost),resources.moveSpd); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::MOVESPD_COLOR); totalCost+=util::GetMoveSpdCost(resourceCost); index++; } if(util::GetRangeCost(resourceCost)!=-1){ DrawResourceAmount(index,util::GetRangeCost(resourceCost),resources.range); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::RANGE_COLOR); totalCost+=util::GetRangeCost(resourceCost); index++; } if(util::GetProcedureCost(resourceCost)!=-1){ DrawResourceAmount(index,util::GetProcedureCost(resourceCost),resources.procedure); pge->DrawDecal(contentPos+vf2d{0,index*6.f},IMAGES[RESOURCE]->Decal(),{0.5,0.5},CONSTANT::PROCEDURE_COLOR); totalCost+=util::GetProcedureCost(resourceCost); index++; } std::string text="Size: "+std::to_string(totalCost)+" bytes"; vi2d size=pge->GetTextSizeProp(text); drawcol=WHITE; if(totalCost+totalUsedMemory>memoryLimit){ pge->FillRectDecal(contentPos+vf2d{-1,float(index*6)},vf2d{resourceBoxRect.size.x-4,7},{160,0,0,192}); drawcol=RED; } pge->DrawShadowStringPropDecal(contentPos+vf2d{0,index*6.f+1},text,drawcol,BLACK,{30/float(size.x),0.5},0.6); index++; } } } void Textbox::UpdatePosition(vf2d newPos){ pos=newPos; } std::string&Textbox::GetCurrentString(){ return text; } void Textbox::SetVisible(bool visible){ this->visible=visible; if(!visible){ SetDefaults(); } } void Textbox::UpdateAndDraw(vf2d pos,PixelGameEngine*pge,Resources&resources,std::vector>&IMAGES,int totalUsedMemory,int memoryLimit){ UpdatePosition(pos); Update(pge); Draw(pge,resources,IMAGES,totalUsedMemory,memoryLimit); } vf2d Textbox::GetSize(){ return maxSize; } void Textbox::SetBackgroundColor(Pixel col){ backCol=col; } bool Textbox::IsVisible(){ return visible; }