Downstream merge with demo branch.
This commit is contained in:
commit
317ea5a672
@ -272,19 +272,19 @@ bool AiL::OnUserCreate(){
|
|||||||
|
|
||||||
ItemInfo::InitializeItems();
|
ItemInfo::InitializeItems();
|
||||||
|
|
||||||
|
InitializeGraphics();
|
||||||
|
InitializeClasses();
|
||||||
|
|
||||||
|
sig::Animation::InitializeAnimations();
|
||||||
|
|
||||||
player=std::make_unique<Warrior>();
|
player=std::make_unique<Warrior>();
|
||||||
|
|
||||||
|
InitializePlayerLevelCap();
|
||||||
|
|
||||||
healthCounter.Initialize(&player->hp,"Interface.HUD Health Tick Rate"_F,"Interface.HUD Health Display Color"_Pixel,"Interface.HUD Heal Damage Color"_Pixel,"Interface.HUD Take Damage Color"_Pixel,"Interface.HUD Health Change Time"_F);
|
healthCounter.Initialize(&player->hp,"Interface.HUD Health Tick Rate"_F,"Interface.HUD Health Display Color"_Pixel,"Interface.HUD Heal Damage Color"_Pixel,"Interface.HUD Take Damage Color"_Pixel,"Interface.HUD Health Change Time"_F);
|
||||||
manaCounter.Initialize(&player->mana,"Interface.HUD Mana Tick Rate"_F,"Interface.HUD Mana Display Color"_Pixel,"Interface.HUD Restore Mana Color"_Pixel,"Interface.HUD Reduce Mana Color"_Pixel,"Interface.HUD Mana Change Time"_F);
|
manaCounter.Initialize(&player->mana,"Interface.HUD Mana Tick Rate"_F,"Interface.HUD Mana Display Color"_Pixel,"Interface.HUD Restore Mana Color"_Pixel,"Interface.HUD Reduce Mana Color"_Pixel,"Interface.HUD Mana Change Time"_F);
|
||||||
|
|
||||||
InitializePlayerLevelCap();
|
|
||||||
|
|
||||||
InitializeGraphics();
|
|
||||||
InitializeClasses();
|
|
||||||
|
|
||||||
Monster::InitializeStrategies();
|
Monster::InitializeStrategies();
|
||||||
//Animations
|
|
||||||
sig::Animation::InitializeAnimations();
|
|
||||||
MonsterData::InitializeMonsterData();
|
MonsterData::InitializeMonsterData();
|
||||||
MonsterData::InitializeNPCData();
|
MonsterData::InitializeNPCData();
|
||||||
|
|
||||||
@ -353,6 +353,7 @@ bool AiL::OnUserCreate(){
|
|||||||
SetupDiscord();
|
SetupDiscord();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
player->InitializeMinimapImage();
|
||||||
minimap.Initialize();
|
minimap.Initialize();
|
||||||
|
|
||||||
gameInitialized=true;
|
gameInitialized=true;
|
||||||
@ -2700,6 +2701,7 @@ void AiL::ChangePlayerClass(Class cl){
|
|||||||
camera.SetTarget(player->GetPos());
|
camera.SetTarget(player->GetPos());
|
||||||
Component<MenuLabel>(CHARACTER_MENU,"Level Class Display")->SetLabel(std::format("Lv{} {}",game->GetPlayer()->Level(),game->GetPlayer()->GetClassName()));
|
Component<MenuLabel>(CHARACTER_MENU,"Level Class Display")->SetLabel(std::format("Lv{} {}",game->GetPlayer()->Level(),game->GetPlayer()->GetClassName()));
|
||||||
Player::moneyListeners=moneyListeners;
|
Player::moneyListeners=moneyListeners;
|
||||||
|
GetPlayer()->InitializeMinimapImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiL::InitializeClasses(){
|
void AiL::InitializeClasses(){
|
||||||
@ -3778,12 +3780,13 @@ void AiL::ResetGame(bool changeToMainMenu){
|
|||||||
game->ClearLoadoutItem(i);
|
game->ClearLoadoutItem(i);
|
||||||
}
|
}
|
||||||
Unlock::Initialize();
|
Unlock::Initialize();
|
||||||
State_OverworldMap::SetStageMarker("Story I");
|
State_OverworldMap::SetStageMarker("Player.Starting Location"_S);
|
||||||
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
||||||
State_OverworldMap::ResetConnectionPoints();
|
State_OverworldMap::ResetConnectionPoints();
|
||||||
SetChapter(1);
|
SetChapter(1);
|
||||||
SaveFile::SetSaveFileName("");
|
SaveFile::SetSaveFileName("");
|
||||||
Tutorial::Initialize();
|
Tutorial::Initialize();
|
||||||
|
minimap.EraseChunkData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiL::OnRequestCompleted(const std::string_view receivedData)const{
|
void AiL::OnRequestCompleted(const std::string_view receivedData)const{
|
||||||
|
@ -42,21 +42,20 @@ All rights reserved.
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
|
INCLUDE_GFX
|
||||||
|
|
||||||
void Minimap::Initialize(){
|
void Minimap::Initialize(){
|
||||||
std::vector<vf2d>enlargedCircle;
|
std::vector<vf2d>enlargedCircle;
|
||||||
for(int i=360;i>=0;i-=4){
|
for(int i=360;i>=0;i-=4){
|
||||||
float angle=util::degToRad(float(i))-PI/2;
|
float angle=util::degToRad(float(i))-PI/2;
|
||||||
if(i==360){enlargedCircle.push_back(vf2d{cos(angle),sin(angle)}*"Minimap.Minimap HUD Size"_I+"Minimap.Minimap HUD Size"_I);}
|
if(i==360){enlargedCircle.push_back(vf2d{cos(angle),sin(angle)}*"Minimap.Minimap HUD Size"_I/2+"Minimap.Minimap HUD Size"_I/2);}
|
||||||
enlargedCircle.push_back(vf2d{cos(angle),sin(angle)}*"Minimap.Minimap HUD Size"_I+"Minimap.Minimap HUD Size"_I);
|
enlargedCircle.push_back(vf2d{cos(angle),sin(angle)}*"Minimap.Minimap HUD Size"_I/2+"Minimap.Minimap HUD Size"_I/2);
|
||||||
}
|
}
|
||||||
mapCircleHud=ViewPort{enlargedCircle};
|
mapCircleHud=ViewPort{enlargedCircle,vi2d{game->ScreenWidth()-"Minimap.Minimap HUD Size"_I-4,4}};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minimap::Reset(){
|
void Minimap::Reset(){
|
||||||
loadedChunks.clear();
|
|
||||||
|
|
||||||
if(minimap.Sprite()==nullptr)minimap.Create(1,1);
|
if(minimap.Sprite()==nullptr)minimap.Create(1,1);
|
||||||
if(cover.Sprite()==nullptr)cover.Create(1,1);
|
if(cover.Sprite()==nullptr)cover.Create(1,1);
|
||||||
|
|
||||||
@ -128,50 +127,66 @@ void Minimap::Reset(){
|
|||||||
game->SetDrawTarget(nullptr);
|
game->SetDrawTarget(nullptr);
|
||||||
|
|
||||||
minimap.Decal()->Update();
|
minimap.Decal()->Update();
|
||||||
|
|
||||||
|
#pragma region Load all minimap chunks already explored
|
||||||
|
for(auto&chunk:loadedChunks[game->GetCurrentMapName()]){
|
||||||
|
vi2d chunkPos={stoi(chunk.substr(0,chunk.find('_'))),stoi(chunk.substr(chunk.find('_')+1))};
|
||||||
|
UpdateChunk(game->GetCurrentMapName(),chunkPos);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minimap::Update(){
|
void Minimap::Update(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minimap::UpdateChunk(const vi2d chunkPos){
|
void Minimap::UpdateChunk(const MapName map,const vi2d chunkPos){
|
||||||
if(!loadedChunks.count(std::format("{}_{}",chunkPos.x,chunkPos.y))){
|
loadedChunks[map].insert(std::format("{}_{}",chunkPos.x,chunkPos.y));
|
||||||
loadedChunks.insert(std::format("{}_{}",chunkPos.x,chunkPos.y));
|
|
||||||
|
if(game->GetCurrentMapName()!=map)return; //Don't update the minimap when the map name doesn't match the current map.
|
||||||
vi2d centerChunkPos=chunkPos*"Minimap.Chunk Size"_I;
|
|
||||||
|
|
||||||
vi2d pixelPos=centerChunkPos-"Minimap.Chunk Size"_I*2;
|
vi2d centerChunkPos=chunkPos*"Minimap.Chunk Size"_I;
|
||||||
vi2d chunkEndPixelPos=centerChunkPos+"Minimap.Chunk Size"_I*4;
|
|
||||||
|
|
||||||
//We start twice the distance we are supposed to outwards.
|
vi2d pixelPos=centerChunkPos-"Minimap.Chunk Size"_I*2;
|
||||||
for(int y=pixelPos.y;y<chunkEndPixelPos.y;y++){
|
vi2d chunkEndPixelPos=centerChunkPos+"Minimap.Chunk Size"_I*4;
|
||||||
for(int x=pixelPos.x;x<chunkEndPixelPos.x;x++){
|
|
||||||
if(cover.Sprite()->GetPixel(x,y).a==255||minimap.Sprite()->GetPixel(x,y).a==0)continue; //Already revealed or invisible anyways.
|
|
||||||
|
|
||||||
vi2d chunk=vi2d{x,y}/"Minimap.Chunk Size"_I;
|
//We start twice the distance we are supposed to outwards.
|
||||||
if(chunk==chunkPos){
|
for(int y=pixelPos.y;y<chunkEndPixelPos.y;y++){
|
||||||
cover.Sprite()->SetPixel(x,y,minimap.Sprite()->GetPixel(x,y));
|
for(int x=pixelPos.x;x<chunkEndPixelPos.x;x++){
|
||||||
}else{
|
if(cover.Sprite()->GetPixel(x,y).a==255||minimap.Sprite()->GetPixel(x,y).a==0)continue; //Already revealed or invisible anyways.
|
||||||
const vi2d chunkOffset={"Minimap.Chunk Size"_I/2,"Minimap.Chunk Size"_I/2};
|
|
||||||
|
|
||||||
const float distance=geom2d::line<float>(centerChunkPos+chunkOffset,vf2d{float(x),float(y)}).length();
|
vi2d chunk=vi2d{x,y}/"Minimap.Chunk Size"_I;
|
||||||
const int alpha=std::clamp(util::lerp(255,0,(distance-"Minimap.Chunk Size"_I)/"Minimap.Chunk Size"_I),0.f,255.f);
|
if(chunk==chunkPos){
|
||||||
|
cover.Sprite()->SetPixel(x,y,minimap.Sprite()->GetPixel(x,y));
|
||||||
|
}else{
|
||||||
|
const vi2d chunkOffset={"Minimap.Chunk Size"_I/2,"Minimap.Chunk Size"_I/2};
|
||||||
|
|
||||||
|
const float distance=geom2d::line<float>(centerChunkPos+chunkOffset,vf2d{float(x),float(y)}).length();
|
||||||
|
const int alpha=std::clamp(util::lerp(255,0,(distance-"Minimap.Chunk Size"_I)/"Minimap.Chunk Size"_I),0.f,255.f);
|
||||||
|
|
||||||
if(cover.Sprite()->GetPixel(x,y).a>alpha)continue; //The distance was uncovered by another closer chunk, don't need to reveal it here.
|
if(cover.Sprite()->GetPixel(x,y).a>alpha)continue; //The distance was uncovered by another closer chunk, don't need to reveal it here.
|
||||||
|
|
||||||
Pixel sourceCol=minimap.Sprite()->GetPixel(x,y);
|
Pixel sourceCol=minimap.Sprite()->GetPixel(x,y);
|
||||||
sourceCol.a=alpha;
|
sourceCol.a=alpha;
|
||||||
cover.Sprite()->SetPixel(x,y,sourceCol);
|
cover.Sprite()->SetPixel(x,y,sourceCol);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cover.Decal()->Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cover.Decal()->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minimap::Draw(){
|
void Minimap::Draw(){
|
||||||
mapCircleHud.DrawRotatedDecal(vf2d{"Minimap.Minimap HUD Size"_I/2.f,"Minimap.Minimap HUD Size"_I/2.f},cover.Decal(),0.f,game->GetPlayer()->GetPos()/24);
|
const vf2d minimapPos=vf2d{float("Minimap.Minimap HUD Size"_I),float("Minimap.Minimap HUD Size"_I)}/2;
|
||||||
mapCircleHud.DrawStringDecal({0,0},"Hello World! Hello World! Hello World! Hello World! \nHello World! Hello World! Hello World! Hello World! \nHello World! Hello World! Hello World! ");
|
if(!game->InBossEncounter())mapCircleHud.DrawRotatedDecal(minimapPos,cover.Decal(),0.f,game->GetPlayer()->GetPos()/game->GetCurrentMapData().tilewidth,vf2d{0.5f,0.5f});
|
||||||
mapCircleHud.drawEdges();
|
game->DrawRotatedDecal(mapCircleHud.GetOffset()+minimapPos,GFX["skill_overlay_icon.png"].Decal(),0.f,GFX["skill_overlay_icon.png"].Sprite()->Size()/2,vf2d{float("Minimap.Minimap HUD Size"_I),float("Minimap.Minimap HUD Size"_I)}/24.f*1.05f);
|
||||||
|
game->DrawRotatedDecal(mapCircleHud.GetOffset()+minimapPos,game->GetPlayer()->GetMinimapImage().Decal(),0.f,vi2d{"Player.Minimap Image Size"_i[0],"Player.Minimap Image Size"_i[1]}/2,{0.5f,0.5f});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Minimap::EraseChunkData(){
|
||||||
|
loadedChunks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unordered_map<MapName,std::unordered_set<std::string>>&Minimap::GetChunkData(){
|
||||||
|
return loadedChunks;
|
||||||
}
|
}
|
@ -46,10 +46,13 @@ public:
|
|||||||
void Update();
|
void Update();
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
void UpdateChunk(const vi2d chunkPos);
|
void UpdateChunk(const MapName map,const vi2d chunkPos);
|
||||||
|
void EraseChunkData();
|
||||||
|
|
||||||
|
const std::unordered_map<MapName,std::unordered_set<std::string>>&GetChunkData();
|
||||||
private:
|
private:
|
||||||
ViewPort mapCircleHud;
|
ViewPort mapCircleHud;
|
||||||
Renderable minimap;
|
Renderable minimap;
|
||||||
Renderable cover;
|
Renderable cover;
|
||||||
std::unordered_set<std::string>loadedChunks;
|
std::unordered_map<MapName,std::unordered_set<std::string>>loadedChunks;
|
||||||
};
|
};
|
@ -111,6 +111,33 @@ void Player::Initialize(){
|
|||||||
cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX);
|
cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::InitializeMinimapImage(){
|
||||||
|
#pragma region Setup Minimap Image
|
||||||
|
minimapImg.Create("Player.Minimap Image Size"_i[0],"Player.Minimap Image Size"_i[1]);
|
||||||
|
game->SetDrawTarget(minimapImg.Sprite());
|
||||||
|
game->SetPixelMode(Pixel::Mode::ALPHA);
|
||||||
|
game->Clear(BLANK);
|
||||||
|
for(int y=0;y<"Player.Minimap Image Size"_i[1];y++){
|
||||||
|
for(int x=0;x<"Player.Minimap Image Size"_i[0];x++){
|
||||||
|
const int radius="Player.Minimap Image Size"_i[0]/2;
|
||||||
|
const vi2d center=vi2d{"Player.Minimap Image Offset"_i[0],"Player.Minimap Image Offset"_i[1]};
|
||||||
|
vi2d imgOffset=vi2d{-"Player.Minimap Image Size"_i[0]/2,-"Player.Minimap Image Size"_i[1]/2}+vi2d{"Player.Minimap Image Offset"_i[0],"Player.Minimap Image Offset"_i[1]};
|
||||||
|
float dist=geom2d::line<float>{imgOffset+vi2d{x,y},center}.length();
|
||||||
|
if(dist>radius)continue;
|
||||||
|
std::string className=GetWalkSAnimation();
|
||||||
|
Animate2D::FrameSequence sequence=ANIMATION_DATA.at(className);
|
||||||
|
Animate2D::Frame frame=sequence.GetFrame(0.f);
|
||||||
|
const Renderable*temp=frame.GetSourceImage();
|
||||||
|
Pixel col=temp->Sprite()->GetPixel(imgOffset+vi2d{x,y});
|
||||||
|
minimapImg.Sprite()->SetPixel({x,y},col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
game->SetDrawTarget(nullptr);
|
||||||
|
game->SetPixelMode(Pixel::Mode::NORMAL);
|
||||||
|
minimapImg.Decal()->Update();
|
||||||
|
#pragma endregion
|
||||||
|
}
|
||||||
|
|
||||||
void Player::ForceSetPos(vf2d pos){
|
void Player::ForceSetPos(vf2d pos){
|
||||||
this->pos=pos;
|
this->pos=pos;
|
||||||
Moved();
|
Moved();
|
||||||
@ -866,7 +893,7 @@ void Player::Moved(){
|
|||||||
ForceSetPos({pos.x,float(game->GetCurrentMapData().playerSpawnLocation.y)});
|
ForceSetPos({pos.x,float(game->GetCurrentMapData().playerSpawnLocation.y)});
|
||||||
}
|
}
|
||||||
|
|
||||||
game->minimap.UpdateChunk(GetPos()/24/"Minimap.Chunk Size"_I);
|
game->minimap.UpdateChunk(game->GetCurrentMapName(),GetPos()/game->GetCurrentMapData().tilewidth/"Minimap.Chunk Size"_I);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::Spin(float duration,float spinSpd){
|
void Player::Spin(float duration,float spinSpd){
|
||||||
@ -1504,4 +1531,8 @@ const float Player::GetAtkGrowthRate()const{
|
|||||||
|
|
||||||
const float Player::GetIframeTime()const{
|
const float Player::GetIframeTime()const{
|
||||||
return iframe_time;
|
return iframe_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Renderable&Player::GetMinimapImage()const{
|
||||||
|
return minimapImg;
|
||||||
}
|
}
|
@ -252,6 +252,7 @@ public:
|
|||||||
const float GetHealthGrowthRate()const;
|
const float GetHealthGrowthRate()const;
|
||||||
const float GetAtkGrowthRate()const;
|
const float GetAtkGrowthRate()const;
|
||||||
const float GetIframeTime()const;
|
const float GetIframeTime()const;
|
||||||
|
const Renderable&GetMinimapImage()const;
|
||||||
private:
|
private:
|
||||||
int hp="Warrior.BaseHealth"_I;
|
int hp="Warrior.BaseHealth"_I;
|
||||||
int mana="Player.BaseMana"_I;
|
int mana="Player.BaseMana"_I;
|
||||||
@ -313,9 +314,11 @@ private:
|
|||||||
//Typical usage is playerInvoked is true on first call, and playerInvoked is false on all subsequent chained calls.
|
//Typical usage is playerInvoked is true on first call, and playerInvoked is false on all subsequent chained calls.
|
||||||
bool _SetY(float y,const bool playerInvoked=true);
|
bool _SetY(float y,const bool playerInvoked=true);
|
||||||
const bool UsingAutoAim()const;
|
const bool UsingAutoAim()const;
|
||||||
|
void InitializeMinimapImage();
|
||||||
bool lowHealthSoundPlayed=false;
|
bool lowHealthSoundPlayed=false;
|
||||||
float lowHealthSoundPlayedTimer=0.f;
|
float lowHealthSoundPlayedTimer=0.f;
|
||||||
float rangerShootAnimationTimer=0.f;
|
float rangerShootAnimationTimer=0.f;
|
||||||
|
Renderable minimapImg; //An image of the character represented on a minimap. Should be 12x12 and generally be a circle.
|
||||||
protected:
|
protected:
|
||||||
const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F;
|
const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F;
|
||||||
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
|
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
|
||||||
|
@ -86,108 +86,123 @@ const void SaveFile::SaveGame(){
|
|||||||
game->SetQuitAllowed(false);
|
game->SetQuitAllowed(false);
|
||||||
|
|
||||||
std::filesystem::create_directories("save_file_path"_S);
|
std::filesystem::create_directories("save_file_path"_S);
|
||||||
utils::datafile saveFile;
|
|
||||||
utils::datafile saveSystemFile;
|
utils::datafile saveSystemFile;
|
||||||
utils::datafile::INITIAL_SETUP_COMPLETE=false;
|
{
|
||||||
for(size_t itemCount=0;auto&item:Inventory::GetInventory()){
|
utils::datafile saveFile;
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Amt"].SetInt(item->Amt());
|
utils::datafile::INITIAL_SETUP_COMPLETE=false;
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Enhancement Level"].SetInt(item->EnhancementLevel());
|
for(size_t itemCount=0;auto&item:Inventory::GetInventory()){
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Item Name"].SetString(item->ActualName());
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Amt"].SetInt(item->Amt());
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Equip Slot"].SetInt(int(Inventory::GetSlotEquippedIn(item)));
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Enhancement Level"].SetInt(item->EnhancementLevel());
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Locked"].SetBool(item->IsLocked());
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Item Name"].SetString(item->ActualName());
|
||||||
uint8_t loadoutSlotNumber=255;
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Equip Slot"].SetInt(int(Inventory::GetSlotEquippedIn(item)));
|
||||||
for(int i=0;i<game->loadout.size();i++){
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Locked"].SetBool(item->IsLocked());
|
||||||
if(item==game->GetLoadoutItem(i)){loadoutSlotNumber=i;break;}
|
uint8_t loadoutSlotNumber=255;
|
||||||
|
for(int i=0;i<game->loadout.size();i++){
|
||||||
|
if(item==game->GetLoadoutItem(i)){loadoutSlotNumber=i;break;}
|
||||||
|
}
|
||||||
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["LoadoutSlot"].SetInt(loadoutSlotNumber);
|
||||||
|
for(const auto&[attr,val]:item->RandomStats()){
|
||||||
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Attributes"][std::string(attr.ActualName())].SetReal(val);
|
||||||
|
}
|
||||||
|
itemCount++;
|
||||||
}
|
}
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["LoadoutSlot"].SetInt(loadoutSlotNumber);
|
saveFile["Player"]["Class"].SetString(game->GetPlayer()->GetClassName());
|
||||||
for(const auto&[attr,val]:item->RandomStats()){
|
saveFile["Player"]["Level"].SetInt(game->GetPlayer()->Level());
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Attributes"][std::string(attr.ActualName())].SetReal(val);
|
saveFile["Player"]["Money"].SetInt(game->GetPlayer()->GetMoney());
|
||||||
|
saveFile["Player"]["Current EXP"].SetInt(game->GetPlayer()->CurrentXP());
|
||||||
|
saveFile["Player"]["Total EXP"].SetInt(game->GetPlayer()->TotalXP());
|
||||||
|
for(const auto&[attr,val]:game->GetPlayer()->GetBaseStats()){
|
||||||
|
saveFile["Player"]["Base Stats"][std::string(attr.ActualName())].SetReal(val);
|
||||||
}
|
}
|
||||||
itemCount++;
|
for(const std::string&unlockName:Unlock::unlocks){
|
||||||
}
|
if(unlockName=="WORLD_MAP")continue; //This is a special exception, because the world map is not an actual stage.
|
||||||
saveFile["Player"]["Class"].SetString(game->GetPlayer()->GetClassName());
|
saveFile["Unlocks"][unlockName].SetString("True");
|
||||||
saveFile["Player"]["Level"].SetInt(game->GetPlayer()->Level());
|
|
||||||
saveFile["Player"]["Money"].SetInt(game->GetPlayer()->GetMoney());
|
|
||||||
saveFile["Player"]["Current EXP"].SetInt(game->GetPlayer()->CurrentXP());
|
|
||||||
saveFile["Player"]["Total EXP"].SetInt(game->GetPlayer()->TotalXP());
|
|
||||||
for(const auto&[attr,val]:game->GetPlayer()->GetBaseStats()){
|
|
||||||
saveFile["Player"]["Base Stats"][std::string(attr.ActualName())].SetReal(val);
|
|
||||||
}
|
|
||||||
for(const std::string&unlockName:Unlock::unlocks){
|
|
||||||
if(unlockName=="WORLD_MAP")continue; //This is a special exception, because the world map is not an actual stage.
|
|
||||||
saveFile["Unlocks"][unlockName].SetString("True");
|
|
||||||
|
|
||||||
auto opt_cp=State_OverworldMap::ConnectionPointFromString(unlockName);
|
auto opt_cp=State_OverworldMap::ConnectionPointFromString(unlockName);
|
||||||
if(!opt_cp.has_value())continue; //Harmless, we probably just deleted the map.
|
if(!opt_cp.has_value())continue; //Harmless, we probably just deleted the map.
|
||||||
if(opt_cp.value()->Visited()){
|
if(opt_cp.value()->Visited()){
|
||||||
saveFile["Unlocks"][unlockName].SetString("True",1U);
|
saveFile["Unlocks"][unlockName].SetString("True",1U);
|
||||||
}else{
|
}else{
|
||||||
saveFile["Unlocks"][unlockName].SetString("False",1U);
|
saveFile["Unlocks"][unlockName].SetString("False",1U);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto&[taskName,task]:Tutorial::taskList){
|
|
||||||
saveFile["Tutorial"][std::to_string(int(taskName))].SetBool(Tutorial::TaskIsComplete(taskName));
|
|
||||||
}
|
|
||||||
|
|
||||||
saveFile["Overworld Map Location"].SetString(State_OverworldMap::GetCurrentConnectionPoint().name);
|
|
||||||
saveFile["Chapter"].SetInt(game->GetCurrentChapter());
|
|
||||||
saveFile["Save Name"].SetString(std::string(GetSaveFileName()));
|
|
||||||
saveFile["Game Time"].SetReal(game->GetRuntime());
|
|
||||||
saveFile["TravelingMerchant"].SetString(std::string(Merchant::GetCurrentTravelingMerchant().GetKeyName()));
|
|
||||||
|
|
||||||
#pragma region Save Keyboard/Controller mappings
|
|
||||||
//NOTE: We are shadowing code from InputKeyboardWindow! If at some point the retrival method for getting input displays changes, we likely will be changing the code here as well!
|
|
||||||
//ALSO NOTE: The menu inputs are saved to the system file while gameplay inputs are per-character and saved to the character settings file!
|
|
||||||
const int menuRowCount=DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()%2==0?DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()/2:DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()/2+1;
|
|
||||||
const int menuColCount=2;
|
|
||||||
for(int row=0;row<menuRowCount;row++){
|
|
||||||
for(int col=0;col<menuColCount;col++){
|
|
||||||
int inputID=row*menuColCount+col;
|
|
||||||
if(DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()%2==1&&col==1&&row==menuRowCount-1)continue; //We only continue on a blank space when we have an odd number of elements.
|
|
||||||
saveSystemFile["Menu Keyboard Input_"+"Inputs.Menu Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Input Displayer",row,col))->GetInput().GetPrimaryKey(KEY).value().GetKeyCode());
|
|
||||||
saveSystemFile["Menu Controller Input_"+"Inputs.Menu Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Input Displayer",row,col))->GetInput().GetPrimaryKey(CONTROLLER).value().GetKeyCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const int ingameControlsRowCount=DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()%2==0?DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2:DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2+1;
|
|
||||||
const int ingameControlsColCount=2;
|
for(auto&[taskName,task]:Tutorial::taskList){
|
||||||
for(int row=0;row<ingameControlsRowCount;row++){
|
saveFile["Tutorial"][std::to_string(int(taskName))].SetBool(Tutorial::TaskIsComplete(taskName));
|
||||||
for(int col=0;col<ingameControlsColCount;col++){
|
}
|
||||||
int inputID=row*menuColCount+col;
|
|
||||||
if(DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()%2==1&&col==1&&row==ingameControlsRowCount-1)continue; //We only continue on a blank space when we have an odd number of elements.
|
saveFile["Overworld Map Location"].SetString(State_OverworldMap::GetCurrentConnectionPoint().name);
|
||||||
saveFile["Gameplay Keyboard Input_"+"Inputs.Gameplay Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Gameplay Input Displayer",row,col))->GetInput().GetPrimaryKey(KEY).value().GetKeyCode());
|
saveFile["Chapter"].SetInt(game->GetCurrentChapter());
|
||||||
saveFile["Gameplay Controller Input_"+"Inputs.Gameplay Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Gameplay Input Displayer",row,col))->GetInput().GetPrimaryKey(CONTROLLER).value().GetKeyCode());
|
saveFile["Save Name"].SetString(std::string(GetSaveFileName()));
|
||||||
|
saveFile["Game Time"].SetReal(game->GetRuntime());
|
||||||
|
saveFile["TravelingMerchant"].SetString(std::string(Merchant::GetCurrentTravelingMerchant().GetKeyName()));
|
||||||
|
|
||||||
|
#pragma region Save Keyboard/Controller mappings
|
||||||
|
//NOTE: We are shadowing code from InputKeyboardWindow! If at some point the retrival method for getting input displays changes, we likely will be changing the code here as well!
|
||||||
|
//ALSO NOTE: The menu inputs are saved to the system file while gameplay inputs are per-character and saved to the character settings file!
|
||||||
|
const int menuRowCount=DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()%2==0?DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()/2:DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()/2+1;
|
||||||
|
const int menuColCount=2;
|
||||||
|
for(int row=0;row<menuRowCount;row++){
|
||||||
|
for(int col=0;col<menuColCount;col++){
|
||||||
|
int inputID=row*menuColCount+col;
|
||||||
|
if(DATA.GetProperty("Inputs.Menu Input Names").GetValueCount()%2==1&&col==1&&row==menuRowCount-1)continue; //We only continue on a blank space when we have an odd number of elements.
|
||||||
|
saveSystemFile["Menu Keyboard Input_"+"Inputs.Menu Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Input Displayer",row,col))->GetInput().GetPrimaryKey(KEY).value().GetKeyCode());
|
||||||
|
saveSystemFile["Menu Controller Input_"+"Inputs.Menu Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Input Displayer",row,col))->GetInput().GetPrimaryKey(CONTROLLER).value().GetKeyCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const int ingameControlsRowCount=DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()%2==0?DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2:DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2+1;
|
||||||
|
const int ingameControlsColCount=2;
|
||||||
|
for(int row=0;row<ingameControlsRowCount;row++){
|
||||||
|
for(int col=0;col<ingameControlsColCount;col++){
|
||||||
|
int inputID=row*menuColCount+col;
|
||||||
|
if(DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()%2==1&&col==1&&row==ingameControlsRowCount-1)continue; //We only continue on a blank space when we have an odd number of elements.
|
||||||
|
saveFile["Gameplay Keyboard Input_"+"Inputs.Gameplay Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Gameplay Input Displayer",row,col))->GetInput().GetPrimaryKey(KEY).value().GetKeyCode());
|
||||||
|
saveFile["Gameplay Controller Input_"+"Inputs.Gameplay Input Names"_s[inputID]].SetInt(Component<InputDisplayComponent>(INPUT_KEY_DISPLAY,std::format("Input_{}_{} Gameplay Input Displayer",row,col))->GetInput().GetPrimaryKey(CONTROLLER).value().GetKeyCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Save System Settings
|
||||||
|
saveSystemFile["BGM Level"].SetReal(Audio::GetBGMVolume());
|
||||||
|
saveSystemFile["SFX Level"].SetReal(Audio::GetSFXVolume());
|
||||||
|
saveSystemFile["Show Max Health"].SetBool(GameSettings::ShowMaxHealth());
|
||||||
|
saveSystemFile["Show Max Mana"].SetBool(GameSettings::ShowMaxMana());
|
||||||
|
saveSystemFile["Screen Shake"].SetBool(GameSettings::ScreenShakeEnabled());
|
||||||
|
saveSystemFile["Controller Rumble"].SetBool(GameSettings::RumbleEnabled());
|
||||||
|
saveSystemFile["Terrain Collision Boxes"].SetBool(GameSettings::TerrainCollisionBoxesEnabled());
|
||||||
|
saveSystemFile["Keyboard Auto-Aim"].SetBool(GameSettings::KeyboardAutoAimEnabled());
|
||||||
|
saveSystemFile["Controller Icons"].SetInt(int(GameSettings::GetIconType()));
|
||||||
|
saveSystemFile["VSync"].SetBool(GameSettings::VSyncEnabled());
|
||||||
|
|
||||||
|
saveSystemFile["Window Pos"].SetInt(game->GetActualWindowPos().x,0);
|
||||||
|
saveSystemFile["Window Pos"].SetInt(game->GetActualWindowPos().y,1);
|
||||||
|
saveSystemFile["Window Size"].SetInt(game->GetWindowSize().x,0);
|
||||||
|
saveSystemFile["Window Size"].SetInt(game->GetWindowSize().y,1);
|
||||||
|
saveSystemFile["Fullscreen"].SetBool(game->IsFullscreen());
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
saveFile["Hash"].SetString("");
|
||||||
|
|
||||||
|
|
||||||
|
for(auto&[mapName,chunks]:game->minimap.GetChunkData()){
|
||||||
|
size_t chunkInd=0;
|
||||||
|
for(auto&chunk:chunks){
|
||||||
|
saveFile["Minimap"][mapName].SetString(chunk,chunkInd);
|
||||||
|
chunkInd++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#pragma region Save System Settings
|
#pragma region Save save file and prep File Hash
|
||||||
saveSystemFile["BGM Level"].SetReal(Audio::GetBGMVolume());
|
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||||
saveSystemFile["SFX Level"].SetReal(Audio::GetSFXVolume());
|
|
||||||
saveSystemFile["Show Max Health"].SetBool(GameSettings::ShowMaxHealth());
|
|
||||||
saveSystemFile["Show Max Mana"].SetBool(GameSettings::ShowMaxMana());
|
|
||||||
saveSystemFile["Screen Shake"].SetBool(GameSettings::ScreenShakeEnabled());
|
|
||||||
saveSystemFile["Controller Rumble"].SetBool(GameSettings::RumbleEnabled());
|
|
||||||
saveSystemFile["Terrain Collision Boxes"].SetBool(GameSettings::TerrainCollisionBoxesEnabled());
|
|
||||||
saveSystemFile["Keyboard Auto-Aim"].SetBool(GameSettings::KeyboardAutoAimEnabled());
|
|
||||||
saveSystemFile["Controller Icons"].SetInt(int(GameSettings::GetIconType()));
|
|
||||||
saveSystemFile["VSync"].SetBool(GameSettings::VSyncEnabled());
|
|
||||||
|
|
||||||
saveSystemFile["Window Pos"].SetInt(game->GetActualWindowPos().x,0);
|
std::string fileHash=util::GetHash("save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||||
saveSystemFile["Window Pos"].SetInt(game->GetActualWindowPos().y,1);
|
saveFile["Hash"].SetString(fileHash);
|
||||||
saveSystemFile["Window Size"].SetInt(game->GetWindowSize().x,0);
|
|
||||||
saveSystemFile["Window Size"].SetInt(game->GetWindowSize().y,1);
|
|
||||||
saveSystemFile["Fullscreen"].SetBool(game->IsFullscreen());
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
saveFile["Hash"].SetString("");
|
|
||||||
|
|
||||||
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
|
||||||
|
|
||||||
std::string fileHash=util::GetHash("save_file_path"_S+std::format("save.{:04}",saveFileID));
|
|
||||||
saveFile["Hash"].SetString(fileHash);
|
|
||||||
|
|
||||||
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); //Once the hash has been computed and added, save the file a second time.
|
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); //Once the hash has been computed and added, save the file a second time.
|
||||||
|
#pragma endregion
|
||||||
|
//WARNING! DO NOT WRITE ANY CODE BELOW HERE!!!!! THE HASH HAS ALREADY BEEN WRITTEN.
|
||||||
|
//FILES BECOME CORRUPTED IF THE SAVE FILE IS MODIFIED FROM HERE ONWARDS.
|
||||||
|
}
|
||||||
utils::datafile::Write(saveSystemFile,"save_file_path"_S+"system.conf");
|
utils::datafile::Write(saveSystemFile,"save_file_path"_S+"system.conf");
|
||||||
utils::datafile metadata;
|
utils::datafile metadata;
|
||||||
if(onlineMode){
|
if(onlineMode){
|
||||||
@ -379,6 +394,15 @@ void SaveFile::LoadFile(){
|
|||||||
game->GetPlayer()->RecalculateEquipStats();
|
game->GetPlayer()->RecalculateEquipStats();
|
||||||
if(loadFile.HasProperty("TravelingMerchant"))Merchant::SetTravelingMerchant(loadFile["TravelingMerchant"].GetString());
|
if(loadFile.HasProperty("TravelingMerchant"))Merchant::SetTravelingMerchant(loadFile["TravelingMerchant"].GetString());
|
||||||
|
|
||||||
|
if(loadFile.HasProperty("Minimap")){
|
||||||
|
for(auto&[key,size]:loadFile["Minimap"].GetKeys()){
|
||||||
|
for(const std::string&chunk:loadFile["Minimap"][key].GetValues()){
|
||||||
|
vi2d chunkPos={stoi(chunk.substr(0,chunk.find('_'))),stoi(chunk.substr(chunk.find('_')+1))};
|
||||||
|
game->minimap.UpdateChunk(key,chunkPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma region Load Keyboard/Controller mappings
|
#pragma region Load Keyboard/Controller mappings
|
||||||
//NOTE: We are shadowing code from InputKeyboardWindow! If at some point the retrival method for getting input displays changes, we likely will be changing the code here as well!
|
//NOTE: We are shadowing code from InputKeyboardWindow! If at some point the retrival method for getting input displays changes, we likely will be changing the code here as well!
|
||||||
const int ingameControlsRowCount=DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()%2==0?DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2:DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2+1;
|
const int ingameControlsRowCount=DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()%2==0?DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2:DATA.GetProperty("Inputs.Gameplay Input Names").GetValueCount()/2+1;
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 1
|
#define VERSION_MINOR 1
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 8817
|
#define VERSION_BUILD 8852
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -3,6 +3,15 @@ Player
|
|||||||
BaseMana = 100
|
BaseMana = 100
|
||||||
MoveSpd = 100
|
MoveSpd = 100
|
||||||
|
|
||||||
|
# Game Map Starting Location
|
||||||
|
Starting Location = Story I
|
||||||
|
|
||||||
|
# Class Minimap Image offset
|
||||||
|
Minimap Image Offset = 12,11
|
||||||
|
|
||||||
|
# Class Minimap Image Size (Total Width and Height, starting from the center going out) Ex: 12 means 6 in both directions.
|
||||||
|
Minimap Image Size = 12,12
|
||||||
|
|
||||||
# Starting base crit rate.
|
# Starting base crit rate.
|
||||||
Crit Rate = 0%
|
Crit Rate = 0%
|
||||||
|
|
||||||
|
BIN
Adventures in Lestoria/assets/ranger-map.png
Normal file
BIN
Adventures in Lestoria/assets/ranger-map.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 733 B |
BIN
Adventures in Lestoria/assets/warrior-map.png
Normal file
BIN
Adventures in Lestoria/assets/warrior-map.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 694 B |
BIN
Adventures in Lestoria/assets/wizard-map.png
Normal file
BIN
Adventures in Lestoria/assets/wizard-map.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 716 B |
@ -23,6 +23,7 @@ namespace olc {
|
|||||||
void clear();
|
void clear();
|
||||||
void drawEdges();
|
void drawEdges();
|
||||||
void setOffset(vf2d offset);
|
void setOffset(vf2d offset);
|
||||||
|
const vf2d&GetOffset();
|
||||||
|
|
||||||
static ViewPort rectViewPort(vf2d topLeft,
|
static ViewPort rectViewPort(vf2d topLeft,
|
||||||
vf2d size,
|
vf2d size,
|
||||||
@ -178,6 +179,10 @@ void olc::ViewPort::setOffset(vf2d offset) {
|
|||||||
this->offset = offset;
|
this->offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vf2d&olc::ViewPort::GetOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
olc::ViewPort
|
olc::ViewPort
|
||||||
olc::ViewPort::rectViewPort(vf2d topLeft, vf2d size, olc::vf2d offset) {
|
olc::ViewPort::rectViewPort(vf2d topLeft, vf2d size, olc::vf2d offset) {
|
||||||
olc::ViewPort newPort={{
|
olc::ViewPort newPort={{
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user