Upstream merge with released demo build.
@ -295,6 +295,36 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "None"
|
"value": "None"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Dev Completion Time - Ranger (s)",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dev Completion Time - Thief (s)",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dev Completion Time - Trapper (s)",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dev Completion Time - Warrior (s)",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dev Completion Time - Witch (s)",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dev Completion Time - Wizard (s)",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Level Type",
|
"name": "Level Type",
|
||||||
"propertyType": "LevelType",
|
"propertyType": "LevelType",
|
||||||
@ -618,6 +648,20 @@
|
|||||||
"tileset"
|
"tileset"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"color": "#fff7ff5d",
|
||||||
|
"drawFill": true,
|
||||||
|
"id": 40,
|
||||||
|
"members": [
|
||||||
|
],
|
||||||
|
"name": "TrialClock",
|
||||||
|
"type": "class",
|
||||||
|
"useAs": [
|
||||||
|
"property",
|
||||||
|
"object",
|
||||||
|
"project"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"color": "#ffa40aa4",
|
"color": "#ffa40aa4",
|
||||||
"drawFill": true,
|
"drawFill": true,
|
||||||
|
@ -206,6 +206,10 @@
|
|||||||
<Command>
|
<Command>
|
||||||
</Command>
|
</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
|
<CustomBuildStep>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</CustomBuildStep>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten|Win32'">
|
||||||
<Link>
|
<Link>
|
||||||
@ -519,6 +523,10 @@
|
|||||||
<SubType>
|
<SubType>
|
||||||
</SubType>
|
</SubType>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="SteamStatsReceivedHandler.h">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="steam\isteamapps.h" />
|
<ClInclude Include="steam\isteamapps.h" />
|
||||||
<ClInclude Include="steam\isteamappticket.h" />
|
<ClInclude Include="steam\isteamappticket.h" />
|
||||||
<ClInclude Include="steam\isteamclient.h" />
|
<ClInclude Include="steam\isteamclient.h" />
|
||||||
@ -816,6 +824,10 @@
|
|||||||
<SubType>
|
<SubType>
|
||||||
</SubType>
|
</SubType>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SteamStatsReceivedHandler.cpp">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="SwordSlash.cpp">
|
<ClCompile Include="SwordSlash.cpp">
|
||||||
<SubType>
|
<SubType>
|
||||||
</SubType>
|
</SubType>
|
||||||
@ -844,6 +856,7 @@
|
|||||||
<ClCompile Include="Wolf.cpp" />
|
<ClCompile Include="Wolf.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="..\read_debug_log.ps1" />
|
||||||
<None Include="ClassDiagram.cd" />
|
<None Include="ClassDiagram.cd" />
|
||||||
<None Include="ClassDiagram2.cd" />
|
<None Include="ClassDiagram2.cd" />
|
||||||
<None Include="cpp.hint" />
|
<None Include="cpp.hint" />
|
||||||
@ -851,6 +864,7 @@
|
|||||||
<None Include="steam\steam_api.json" />
|
<None Include="steam\steam_api.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Text Include="assets\config\Achievements.txt" />
|
||||||
<Text Include="assets\config\audio\audio.txt" />
|
<Text Include="assets\config\audio\audio.txt" />
|
||||||
<Text Include="assets\config\audio\bgm.txt" />
|
<Text Include="assets\config\audio\bgm.txt" />
|
||||||
<Text Include="assets\config\audio\environmentalaudio.txt" />
|
<Text Include="assets\config\audio\environmentalaudio.txt" />
|
||||||
|
@ -998,6 +998,9 @@
|
|||||||
<ClCompile Include="SteamKeyboardCallbackHandler.cpp">
|
<ClCompile Include="SteamKeyboardCallbackHandler.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SteamStatsReceivedHandler.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="cpp.hint" />
|
<None Include="cpp.hint" />
|
||||||
@ -1009,6 +1012,7 @@
|
|||||||
<None Include="steam\steam_api.json">
|
<None Include="steam\steam_api.json">
|
||||||
<Filter>Header Files\steam</Filter>
|
<Filter>Header Files\steam</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="..\read_debug_log.ps1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="InitialConcept.txt">
|
<Text Include="InitialConcept.txt">
|
||||||
@ -1159,6 +1163,9 @@
|
|||||||
<Text Include="assets\config\credits.txt">
|
<Text Include="assets\config\credits.txt">
|
||||||
<Filter>Configurations</Filter>
|
<Filter>Configurations</Filter>
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text Include="assets\config\Achievements.txt">
|
||||||
|
<Filter>Configurations</Filter>
|
||||||
|
</Text>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="assets\heart.ico">
|
<Image Include="assets\heart.ico">
|
||||||
|
@ -80,6 +80,7 @@ All rights reserved.
|
|||||||
#include "LoadingScreen.h"
|
#include "LoadingScreen.h"
|
||||||
#include "Tutorial.h"
|
#include "Tutorial.h"
|
||||||
#include "SteamKeyboardCallbackHandler.h"
|
#include "SteamKeyboardCallbackHandler.h"
|
||||||
|
#include "SteamStatsReceivedHandler.h"
|
||||||
|
|
||||||
INCLUDE_EMITTER_LIST
|
INCLUDE_EMITTER_LIST
|
||||||
INCLUDE_ITEM_CATEGORIES
|
INCLUDE_ITEM_CATEGORIES
|
||||||
@ -232,6 +233,9 @@ AiL::AiL()
|
|||||||
std::string CREDITS_CONFIG = CONFIG_PATH + "credits_config"_S;
|
std::string CREDITS_CONFIG = CONFIG_PATH + "credits_config"_S;
|
||||||
utils::datafile::Read(DATA,CREDITS_CONFIG);
|
utils::datafile::Read(DATA,CREDITS_CONFIG);
|
||||||
|
|
||||||
|
std::string ACHIEVEMENT_CONFIG = CONFIG_PATH + "achievement_config"_S;
|
||||||
|
utils::datafile::Read(DATA,ACHIEVEMENT_CONFIG);
|
||||||
|
|
||||||
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
|
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
|
||||||
|
|
||||||
sAppName = "GAME_NAME"_S;
|
sAppName = "GAME_NAME"_S;
|
||||||
@ -334,6 +338,9 @@ bool AiL::OnUserCreate(){
|
|||||||
if(steamKeyboardCallbackListener==nullptr){
|
if(steamKeyboardCallbackListener==nullptr){
|
||||||
steamKeyboardCallbackListener=new SteamKeyboardCallbackHandler();
|
steamKeyboardCallbackListener=new SteamKeyboardCallbackHandler();
|
||||||
}
|
}
|
||||||
|
if(steamStatsReceivedHandlerListener==nullptr){
|
||||||
|
steamStatsReceivedHandlerListener=new SteamStatsReceivedHandler();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||||||
@ -446,6 +453,7 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
if(KEY_MENU.Released()){
|
if(KEY_MENU.Released()){
|
||||||
Menu::OpenMenu(MenuType::PAUSE);
|
Menu::OpenMenu(MenuType::PAUSE);
|
||||||
}
|
}
|
||||||
|
float animationSpd=0.f;
|
||||||
if(player->GetVelocity().mag()<"Player.Move Allowed Velocity Lower Limit"_F&&player->CanMove()){
|
if(player->GetVelocity().mag()<"Player.Move Allowed Velocity Lower Limit"_F&&player->CanMove()){
|
||||||
auto GetPlayerStaircaseDirection=[&](){
|
auto GetPlayerStaircaseDirection=[&](){
|
||||||
for(LayerTag&layer:MAP_DATA[GetCurrentLevel()].LayerData){
|
for(LayerTag&layer:MAP_DATA[GetCurrentLevel()].LayerData){
|
||||||
@ -462,20 +470,26 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
std::string staircaseDirection=GetPlayerStaircaseDirection();
|
std::string staircaseDirection=GetPlayerStaircaseDirection();
|
||||||
vf2d newAimingAngle{};
|
vf2d newAimingAngle{};
|
||||||
if(RightHeld()){
|
if(RightHeld()){
|
||||||
player->SetX(player->GetX()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
float moveAmt="Player.MoveSpd"_F;
|
||||||
player->movementVelocity.x="Player.MoveSpd"_F;
|
if(Input::UsingGamepad()&&KEY_SCROLLHORZ_L.Analog()>=0.2f){
|
||||||
|
float controllerAmt=abs(KEY_SCROLLHORZ_L.Analog());
|
||||||
|
if(controllerAmt>=0.6f)controllerAmt=1.f; //Edge zone.
|
||||||
|
if(controllerAmt>animationSpd){
|
||||||
|
animationSpd=controllerAmt;
|
||||||
|
}
|
||||||
|
moveAmt*=controllerAmt;
|
||||||
|
}else animationSpd=1.f;
|
||||||
|
player->SetX(player->GetX()+fElapsedTime*moveAmt*player->GetMoveSpdMult());
|
||||||
|
player->movementVelocity.x=moveAmt*fElapsedTime*player->GetMoveSpdMult();
|
||||||
if(staircaseDirection=="RIGHT"){
|
if(staircaseDirection=="RIGHT"){
|
||||||
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||||||
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F;
|
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult();
|
||||||
} else
|
} else
|
||||||
if(staircaseDirection=="LEFT"){
|
if(staircaseDirection=="LEFT"){
|
||||||
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||||||
player->movementVelocity.y="Player.StaircaseClimbSpd"_F;
|
player->movementVelocity.y="Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult();
|
||||||
}
|
}
|
||||||
player->SetFacingDirection(RIGHT);
|
player->SetFacingDirection(RIGHT);
|
||||||
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
|
||||||
player->UpdateWalkingAnimation(RIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
newAimingAngle+=vf2d{1,0};
|
newAimingAngle+=vf2d{1,0};
|
||||||
|
|
||||||
@ -483,21 +497,25 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
heldDownMovementKey=true;
|
heldDownMovementKey=true;
|
||||||
}
|
}
|
||||||
if(LeftHeld()){
|
if(LeftHeld()){
|
||||||
player->SetX(player->GetX()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
float moveAmt="Player.MoveSpd"_F;
|
||||||
player->movementVelocity.x=-"Player.MoveSpd"_F;
|
if(Input::UsingGamepad()&&KEY_SCROLLHORZ_L.Analog()<=-0.2f){
|
||||||
|
float controllerAmt=abs(KEY_SCROLLHORZ_L.Analog());
|
||||||
|
controllerAmt+=0.2f;
|
||||||
|
if(controllerAmt>=0.6f)controllerAmt=1.f; //Edge zone.
|
||||||
|
if(controllerAmt>animationSpd){
|
||||||
|
animationSpd=controllerAmt;
|
||||||
|
}
|
||||||
|
moveAmt*=controllerAmt;
|
||||||
|
}else animationSpd=1.f;
|
||||||
|
player->SetX(player->GetX()-fElapsedTime*moveAmt*player->GetMoveSpdMult());
|
||||||
|
player->movementVelocity.x=-moveAmt*fElapsedTime*player->GetMoveSpdMult();
|
||||||
if(staircaseDirection=="RIGHT"){
|
if(staircaseDirection=="RIGHT"){
|
||||||
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
player->SetY(player->GetY()+"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||||||
player->movementVelocity.y="Player.StaircaseClimbSpd"_F;
|
player->movementVelocity.y="Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult();
|
||||||
} else
|
} else
|
||||||
if(staircaseDirection=="LEFT"){
|
if(staircaseDirection=="LEFT"){
|
||||||
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
player->SetY(player->GetY()-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult());
|
||||||
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F;
|
player->movementVelocity.y=-"Player.StaircaseClimbSpd"_F*fElapsedTime*player->GetMoveSpdMult();
|
||||||
}
|
|
||||||
if(setIdleAnimation){
|
|
||||||
player->SetFacingDirection(LEFT);
|
|
||||||
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
|
||||||
player->UpdateWalkingAnimation(LEFT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newAimingAngle-=vf2d{1,0};
|
newAimingAngle-=vf2d{1,0};
|
||||||
@ -506,14 +524,18 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
heldDownMovementKey=true;
|
heldDownMovementKey=true;
|
||||||
}
|
}
|
||||||
if(UpHeld()){
|
if(UpHeld()){
|
||||||
player->SetY(player->GetY()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
float moveAmt="Player.MoveSpd"_F;
|
||||||
player->movementVelocity.y=-"Player.MoveSpd"_F*fElapsedTime;
|
if(Input::UsingGamepad()&&KEY_SCROLLVERT_L.Analog()<=-0.2f){
|
||||||
if(setIdleAnimation){
|
float controllerAmt=abs(KEY_SCROLLVERT_L.Analog());
|
||||||
player->SetFacingDirection(UP);
|
controllerAmt+=0.2f;
|
||||||
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
if(controllerAmt>=0.6f)controllerAmt=1.f; //Edge zone.
|
||||||
player->UpdateWalkingAnimation(UP);
|
if(controllerAmt>animationSpd){
|
||||||
}
|
animationSpd=controllerAmt;
|
||||||
}
|
}
|
||||||
|
moveAmt*=controllerAmt;
|
||||||
|
}else animationSpd=1.f;
|
||||||
|
player->SetY(player->GetY()-fElapsedTime*moveAmt*player->GetMoveSpdMult());
|
||||||
|
player->movementVelocity.y=-moveAmt*fElapsedTime*player->GetMoveSpdMult();
|
||||||
|
|
||||||
newAimingAngle-=vf2d{0,1};
|
newAimingAngle-=vf2d{0,1};
|
||||||
|
|
||||||
@ -521,14 +543,18 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
heldDownMovementKey=true;
|
heldDownMovementKey=true;
|
||||||
}
|
}
|
||||||
if(DownHeld()){
|
if(DownHeld()){
|
||||||
player->SetY(player->GetY()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
|
float moveAmt="Player.MoveSpd"_F;
|
||||||
player->movementVelocity.y="Player.MoveSpd"_F*fElapsedTime;
|
if(Input::UsingGamepad()&&KEY_SCROLLVERT_L.Analog()>=0.2f){
|
||||||
if(setIdleAnimation){
|
float controllerAmt=abs(KEY_SCROLLVERT_L.Analog());
|
||||||
player->SetFacingDirection(DOWN);
|
controllerAmt+=0.2f;
|
||||||
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
if(controllerAmt>=0.6f)controllerAmt=1.f; //Edge zone.
|
||||||
player->UpdateWalkingAnimation(DOWN);
|
if(controllerAmt>animationSpd){
|
||||||
}
|
animationSpd=controllerAmt;
|
||||||
}
|
}
|
||||||
|
moveAmt*=controllerAmt;
|
||||||
|
}else animationSpd=1.f;
|
||||||
|
player->SetY(player->GetY()+fElapsedTime*moveAmt*player->GetMoveSpdMult());
|
||||||
|
player->movementVelocity.y=moveAmt*fElapsedTime*player->GetMoveSpdMult();
|
||||||
|
|
||||||
newAimingAngle+=vf2d{0,1};
|
newAimingAngle+=vf2d{0,1};
|
||||||
|
|
||||||
@ -539,6 +565,23 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
player->aimingAngle=newAimingAngle.norm().polar();
|
player->aimingAngle=newAimingAngle.norm().polar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(heldDownMovementKey){
|
||||||
|
if(abs(player->movementVelocity.x)>abs(player->movementVelocity.y)){ //Greater Horizontal movement.
|
||||||
|
if(player->movementVelocity.x!=0.f){
|
||||||
|
player->SetFacingDirection(player->movementVelocity.x>0?RIGHT:LEFT);
|
||||||
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||||||
|
player->UpdateWalkingAnimation(player->GetFacingDirection(),animationSpd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{ //Greater Vertical movement.
|
||||||
|
if(player->movementVelocity.y!=0.f){
|
||||||
|
player->SetFacingDirection(player->movementVelocity.y>0?DOWN:UP);
|
||||||
|
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
|
||||||
|
player->UpdateWalkingAnimation(player->GetFacingDirection(),animationSpd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if(UpReleased()){
|
if(UpReleased()){
|
||||||
player->SetLastReleasedMovementKey(UP);
|
player->SetLastReleasedMovementKey(UP);
|
||||||
player->movementVelocity.y=0;
|
player->movementVelocity.y=0;
|
||||||
@ -605,7 +648,7 @@ void AiL::HandleUserInput(float fElapsedTime){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(heldDownMovementKey){
|
if(heldDownMovementKey){
|
||||||
player->footstepTimer+=GetElapsedTime();
|
player->footstepTimer+=GetElapsedTime()*animationSpd;
|
||||||
if(player->footstepTimer>"Player.Footstep Timer"_F){
|
if(player->footstepTimer>"Player.Footstep Timer"_F){
|
||||||
player->footstepTimer-="Player.Footstep Timer"_F;
|
player->footstepTimer-="Player.Footstep Timer"_F;
|
||||||
|
|
||||||
@ -2461,6 +2504,9 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){
|
|||||||
});
|
});
|
||||||
|
|
||||||
LoadingScreen::AddPhase([&](){
|
LoadingScreen::AddPhase([&](){
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
)
|
||||||
ClearGarbage();
|
ClearGarbage();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@ -2693,6 +2739,9 @@ bool Steam_Init(){
|
|||||||
LOG(std::format("STEAM[{}]: {}",severity,std::string(message)));
|
LOG(std::format("STEAM[{}]: {}",severity,std::string(message)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
SteamUserStats()->RequestCurrentStats();
|
||||||
|
)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -3705,7 +3754,6 @@ void AiL::ResetGame(bool changeToMainMenu){
|
|||||||
for(int i=0;i<GetLoadoutSize();i++){
|
for(int i=0;i<GetLoadoutSize();i++){
|
||||||
game->ClearLoadoutItem(i);
|
game->ClearLoadoutItem(i);
|
||||||
}
|
}
|
||||||
Unlock::unlocks.clear();
|
|
||||||
Unlock::Initialize();
|
Unlock::Initialize();
|
||||||
State_OverworldMap::SetStageMarker("Story I");
|
State_OverworldMap::SetStageMarker("Story I");
|
||||||
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
||||||
@ -3886,3 +3934,7 @@ void AiL::ActivateActionSetForAllControllers(InputActionSetHandle_t actionSetHan
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float AiL::GetEncounterDuration()const{
|
||||||
|
return encounterDuration;
|
||||||
|
}
|
@ -59,6 +59,7 @@ All rights reserved.
|
|||||||
|
|
||||||
|
|
||||||
class SteamKeyboardCallbackHandler;
|
class SteamKeyboardCallbackHandler;
|
||||||
|
class SteamStatsReceivedHandler;
|
||||||
|
|
||||||
#define CreateBullet(type) BULLET_LIST.push_back(std::make_unique<type>(type
|
#define CreateBullet(type) BULLET_LIST.push_back(std::make_unique<type>(type
|
||||||
#define EndBullet ));
|
#define EndBullet ));
|
||||||
@ -189,6 +190,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
Audio audioEngine;
|
Audio audioEngine;
|
||||||
SteamKeyboardCallbackHandler*steamKeyboardCallbackListener=nullptr;
|
SteamKeyboardCallbackHandler*steamKeyboardCallbackListener=nullptr;
|
||||||
|
SteamStatsReceivedHandler*steamStatsReceivedHandlerListener=nullptr;
|
||||||
public:
|
public:
|
||||||
AiL();
|
AiL();
|
||||||
bool OnUserCreate() override;
|
bool OnUserCreate() override;
|
||||||
@ -316,6 +318,7 @@ public:
|
|||||||
rcode LoadResource(Renderable&renderable,std::string_view imgPath,bool filter=false,bool clamp=true);
|
rcode LoadResource(Renderable&renderable,std::string_view imgPath,bool filter=false,bool clamp=true);
|
||||||
void UpdateMonsters();
|
void UpdateMonsters();
|
||||||
void ActivateActionSetForAllControllers(InputActionSetHandle_t actionSetHandle);
|
void ActivateActionSetForAllControllers(InputActionSetHandle_t actionSetHandle);
|
||||||
|
const float GetEncounterDuration()const;
|
||||||
|
|
||||||
struct TileGroupData{
|
struct TileGroupData{
|
||||||
vi2d tilePos;
|
vi2d tilePos;
|
||||||
|
@ -61,25 +61,25 @@ void sig::Animation::InitializeAnimations(){
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto SetupClassWalkIdleAnimations=[&](Renderable&sheet,std::string className){
|
auto SetupClassWalkIdleAnimations=[&](Renderable&sheet,std::string className){
|
||||||
Animate2D::FrameSequence pl_walk_s{0.2f};
|
Animate2D::FrameSequence pl_walk_s{"Player.WalkingFrameSpd"_F};
|
||||||
pl_walk_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
|
pl_walk_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
|
||||||
pl_walk_s.AddFrame({&sheet,{vi2d{1,0}*24,{24,24}}});
|
pl_walk_s.AddFrame({&sheet,{vi2d{1,0}*24,{24,24}}});
|
||||||
pl_walk_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
|
pl_walk_s.AddFrame({&sheet,{vi2d{0,0}*24,{24,24}}});
|
||||||
pl_walk_s.AddFrame({&sheet,{vi2d{2,0}*24,{24,24}}});
|
pl_walk_s.AddFrame({&sheet,{vi2d{2,0}*24,{24,24}}});
|
||||||
ANIMATION_DATA[className+"_WALK_S"]=pl_walk_s;
|
ANIMATION_DATA[className+"_WALK_S"]=pl_walk_s;
|
||||||
Animate2D::FrameSequence pl_walk_e{0.2f};
|
Animate2D::FrameSequence pl_walk_e{"Player.WalkingFrameSpd"_F};
|
||||||
pl_walk_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
|
pl_walk_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
|
||||||
pl_walk_e.AddFrame({&sheet,{vi2d{1,3}*24,{24,24}}});
|
pl_walk_e.AddFrame({&sheet,{vi2d{1,3}*24,{24,24}}});
|
||||||
pl_walk_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
|
pl_walk_e.AddFrame({&sheet,{vi2d{0,3}*24,{24,24}}});
|
||||||
pl_walk_e.AddFrame({&sheet,{vi2d{2,3}*24,{24,24}}});
|
pl_walk_e.AddFrame({&sheet,{vi2d{2,3}*24,{24,24}}});
|
||||||
ANIMATION_DATA[className+"_WALK_E"]=pl_walk_e;
|
ANIMATION_DATA[className+"_WALK_E"]=pl_walk_e;
|
||||||
Animate2D::FrameSequence pl_walk_w{0.2f};
|
Animate2D::FrameSequence pl_walk_w{"Player.WalkingFrameSpd"_F};
|
||||||
pl_walk_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
|
pl_walk_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
|
||||||
pl_walk_w.AddFrame({&sheet,{vi2d{1,2}*24,{24,24}}});
|
pl_walk_w.AddFrame({&sheet,{vi2d{1,2}*24,{24,24}}});
|
||||||
pl_walk_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
|
pl_walk_w.AddFrame({&sheet,{vi2d{0,2}*24,{24,24}}});
|
||||||
pl_walk_w.AddFrame({&sheet,{vi2d{2,2}*24,{24,24}}});
|
pl_walk_w.AddFrame({&sheet,{vi2d{2,2}*24,{24,24}}});
|
||||||
ANIMATION_DATA[className+"_WALK_W"]=pl_walk_w;
|
ANIMATION_DATA[className+"_WALK_W"]=pl_walk_w;
|
||||||
Animate2D::FrameSequence pl_walk_n{0.2f};
|
Animate2D::FrameSequence pl_walk_n{"Player.WalkingFrameSpd"_F};
|
||||||
pl_walk_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
|
pl_walk_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
|
||||||
pl_walk_n.AddFrame({&sheet,{vi2d{1,1}*24,{24,24}}});
|
pl_walk_n.AddFrame({&sheet,{vi2d{1,1}*24,{24,24}}});
|
||||||
pl_walk_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
|
pl_walk_n.AddFrame({&sheet,{vi2d{0,1}*24,{24,24}}});
|
||||||
|
@ -50,6 +50,9 @@ All rights reserved.
|
|||||||
#include "SoundEffect.h"
|
#include "SoundEffect.h"
|
||||||
#include "ProgressBar.h"
|
#include "ProgressBar.h"
|
||||||
#include "MenuItemLabel.h"
|
#include "MenuItemLabel.h"
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/isteamuserstats.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
INCLUDE_GFX
|
INCLUDE_GFX
|
||||||
@ -99,6 +102,17 @@ namespace CharacterMenuWindow{
|
|||||||
if(!comp.expired()){
|
if(!comp.expired()){
|
||||||
if(SelectedEquipIsDifferent(comp)){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
|
if(SelectedEquipIsDifferent(comp)){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
|
||||||
Inventory::EquipItem(comp.lock()->GetItem(),EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE)));
|
Inventory::EquipItem(comp.lock()->GetItem(),EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE)));
|
||||||
|
|
||||||
|
#pragma region Fully Decked Out Achievement
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
datafile&unlock=DATA.GetProperty("Achievement.Equip Unlocks.Fully Decked Out");
|
||||||
|
if(Inventory::EquipsFullyMaxedOut(unlock["Weapon Max Level"].GetInt(),unlock["Armor Max Level"].GetInt())){
|
||||||
|
SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
if(Menu::IsCurrentlyActive(data.menu.GetType())){
|
if(Menu::IsCurrentlyActive(data.menu.GetType())){
|
||||||
SoundEffect::PlaySFX(comp.lock()->GetItem().lock()->UseSound(),SoundEffect::CENTERED);
|
SoundEffect::PlaySFX(comp.lock()->GetItem().lock()->UseSound(),SoundEffect::CENTERED);
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,15 @@ All rights reserved.
|
|||||||
*/
|
*/
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Ability.h"
|
#include <vector>
|
||||||
#include "Animation.h"
|
#include <string>
|
||||||
|
#include "DEFINES.h"
|
||||||
|
#include "olcUTIL_DataFile.h"
|
||||||
|
|
||||||
#undef GetClassInfo
|
#undef GetClassInfo
|
||||||
|
|
||||||
//Classes have bit-wise operator capabilities.
|
INCLUDE_DATA
|
||||||
|
|
||||||
enum Class{
|
enum Class{
|
||||||
ANY=0,
|
ANY=0,
|
||||||
WARRIOR=1,
|
WARRIOR=1,
|
||||||
@ -49,5 +52,15 @@ enum Class{
|
|||||||
RANGER=4,
|
RANGER=4,
|
||||||
TRAPPER=8,
|
TRAPPER=8,
|
||||||
WIZARD=16,
|
WIZARD=16,
|
||||||
WITCH=32
|
WITCH=32,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace classutils{//Classes have bit-wise operator capabilities.
|
||||||
|
static inline Class StringToClass(std::string className){
|
||||||
|
const std::vector<std::string>&classList=DATA["class_list"].GetValues();
|
||||||
|
auto it=std::find(classList.begin(),classList.end(),className);
|
||||||
|
if(it==classList.end())ERR(std::format("WARNING! Class {} does not exist!",className));
|
||||||
|
int element=int(std::distance(classList.begin(),it));
|
||||||
|
return Class(1<<element); //Yes...It's bitwise flags, who in god's name knows why I did this.
|
||||||
|
};
|
||||||
};
|
};
|
@ -54,15 +54,7 @@ struct ClassInfo{
|
|||||||
Ability*rightClickAbility;
|
Ability*rightClickAbility;
|
||||||
};
|
};
|
||||||
|
|
||||||
class classutils{
|
namespace classutils{
|
||||||
public:
|
|
||||||
static inline Class StringToClass(std::string className){
|
|
||||||
const std::vector<std::string>&classList=DATA["class_list"].GetValues();
|
|
||||||
auto it=std::find(classList.begin(),classList.end(),className);
|
|
||||||
if(it==classList.end())ERR(std::format("WARNING! Class {} does not exist!",className));
|
|
||||||
int element=int(std::distance(classList.begin(),it));
|
|
||||||
return Class(1<<element); //Yes...It's bitwise flags, who in god's name knows why I did this.
|
|
||||||
};
|
|
||||||
static inline ClassInfo GetClassInfo(std::string className){
|
static inline ClassInfo GetClassInfo(std::string className){
|
||||||
ClassInfo data{
|
ClassInfo data{
|
||||||
DATA.GetProperty(className+".ClassName").GetString(),
|
DATA.GetProperty(className+".ClassName").GetString(),
|
||||||
|
@ -47,6 +47,9 @@ All rights reserved.
|
|||||||
#include "SoundEffect.h"
|
#include "SoundEffect.h"
|
||||||
#include "ClassInfo.h"
|
#include "ClassInfo.h"
|
||||||
#include "RowInventoryScrollableWindowComponent.h"
|
#include "RowInventoryScrollableWindowComponent.h"
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/isteamuserstats.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
INCLUDE_DATA
|
INCLUDE_DATA
|
||||||
@ -840,8 +843,10 @@ void Inventory::EquipItem(const std::weak_ptr<Item>it,EquipSlot slot){
|
|||||||
if(equippedSlot!=EquipSlot::NONE)UnequipItem(equippedSlot);
|
if(equippedSlot!=EquipSlot::NONE)UnequipItem(equippedSlot);
|
||||||
if(!GetEquip(slot).expired())UnequipItem(slot);
|
if(!GetEquip(slot).expired())UnequipItem(slot);
|
||||||
Inventory::equipment[slot]=it;
|
Inventory::equipment[slot]=it;
|
||||||
|
|
||||||
game->GetPlayer()->RecalculateEquipStats();
|
game->GetPlayer()->RecalculateEquipStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
void Inventory::UnequipItem(EquipSlot slot){
|
void Inventory::UnequipItem(EquipSlot slot){
|
||||||
Inventory::equipment[slot]=Item::BLANK;
|
Inventory::equipment[slot]=Item::BLANK;
|
||||||
game->GetPlayer()->RecalculateEquipStats();
|
game->GetPlayer()->RecalculateEquipStats();
|
||||||
@ -924,6 +929,33 @@ void Item::EnhanceItem(uint8_t qty){
|
|||||||
|
|
||||||
enhancementLevel++;
|
enhancementLevel++;
|
||||||
|
|
||||||
|
#pragma region Achievements
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
// Fully Decked Out Achievement
|
||||||
|
datafile&unlock=DATA.GetProperty("Achievement.Equip Unlocks.Fully Decked Out");
|
||||||
|
if(Inventory::EquipsFullyMaxedOut(unlock["Weapon Max Level"].GetInt(),unlock["Armor Max Level"].GetInt())){
|
||||||
|
SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
// Equipment achievement unlocks
|
||||||
|
for(auto&[key,size]:DATA.GetProperty("Achievement.Equip Unlocks")){
|
||||||
|
datafile&unlock=DATA.GetProperty(std::format("Achievement.Equip Unlocks.{}",key));
|
||||||
|
if(!(unlock.HasProperty("Upgrade Requirement")&&unlock.HasProperty("Equip Slot")))continue; //Ignore any achievements that don't have an upgrade requirement/equipment slot defined.
|
||||||
|
if(EnhancementLevel()>=unlock["Upgrade Requirement"].GetInt()){
|
||||||
|
EquipSlot validSlots=EquipSlot::NONE;
|
||||||
|
for(const std::string&slot:unlock["Equip Slot"].GetValues()){
|
||||||
|
validSlots|=ItemInfo::StringToEquipSlot(slot); //Collect all the bits that this equipment can fall under.
|
||||||
|
}
|
||||||
|
if(GetEquipSlot()&validSlots){
|
||||||
|
//This piece of gear matches one of the provided slots.
|
||||||
|
SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
const CraftingRequirement&consumedResources=GetEnhancementInfo()[EnhancementLevel()].craftingRequirement;
|
const CraftingRequirement&consumedResources=GetEnhancementInfo()[EnhancementLevel()].craftingRequirement;
|
||||||
|
|
||||||
for(const auto&[name,amt]:consumedResources.GetItems()){
|
for(const auto&[name,amt]:consumedResources.GetItems()){
|
||||||
@ -1285,3 +1317,24 @@ void Item::Lock(){
|
|||||||
void Item::Unlock(){
|
void Item::Unlock(){
|
||||||
locked=false;
|
locked=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Specifically for the "Fully Decked Out" achievement.
|
||||||
|
const bool Inventory::EquipsFullyMaxedOut(int maxWeaponLevel,int maxArmorLevel){
|
||||||
|
for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){
|
||||||
|
EquipSlot slot=EquipSlot(i);
|
||||||
|
if(!ISBLANK(Inventory::GetEquip(slot))){
|
||||||
|
std::shared_ptr<Item>equip=Inventory::GetEquip(slot).lock();
|
||||||
|
if(!(equip->IsAccessory()||
|
||||||
|
(equip->IsWeapon()&&equip->EnhancementLevel()>=maxWeaponLevel)||
|
||||||
|
(equip->IsArmor()&&equip->EnhancementLevel()>=maxArmorLevel))
|
||||||
|
){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EquipSlot ItemInfo::StringToEquipSlot(std::string_view slotName){
|
||||||
|
return nameToEquipSlot[std::string(slotName)];
|
||||||
|
}
|
@ -269,6 +269,7 @@ public:
|
|||||||
static void AddLoadoutItemUsed(IT item,int slot);
|
static void AddLoadoutItemUsed(IT item,int slot);
|
||||||
static void ResetLoadoutItemsUsed();
|
static void ResetLoadoutItemsUsed();
|
||||||
static void GivePlayerLoadoutItemsUsed();
|
static void GivePlayerLoadoutItemsUsed();
|
||||||
|
static const bool EquipsFullyMaxedOut(int maxWeaponLevel=10,int maxArmorLevel=10);
|
||||||
|
|
||||||
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);
|
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);
|
||||||
//Makes sure this is a valid category. Will error out if it doesn't exist! Use for ERROR HANDLING!
|
//Makes sure this is a valid category. Will error out if it doesn't exist! Use for ERROR HANDLING!
|
||||||
@ -338,6 +339,7 @@ public:
|
|||||||
const std::string&Description()const;
|
const std::string&Description()const;
|
||||||
const ITCategory Category()const;
|
const ITCategory Category()const;
|
||||||
const::Decal*const Decal()const;
|
const::Decal*const Decal()const;
|
||||||
|
static const EquipSlot StringToEquipSlot(std::string_view slotName);
|
||||||
/*
|
/*
|
||||||
For the useFunc, return true if the item can be used, false otherwise.
|
For the useFunc, return true if the item can be used, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
@ -79,8 +79,10 @@ void Menu::InitializeLevelCompleteWindow(){
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto nextButtonAction=[](MenuFuncData data){
|
auto nextButtonAction=[](MenuFuncData data){
|
||||||
|
if(Component<MenuLabel>(LEVEL_COMPLETE,"Stage Complete Label")->GetLabel()!="Stage Summary"){ //If the label says stage summary, we didn't actually complete the level. Don't unlock anything new for the player.
|
||||||
Unlock::UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
|
Unlock::UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
|
||||||
Merchant::RandomizeTravelingMerchant();
|
Merchant::RandomizeTravelingMerchant();
|
||||||
|
}
|
||||||
State_LevelComplete::TurnOffXPSound();
|
State_LevelComplete::TurnOffXPSound();
|
||||||
GameState::ChangeState(States::GAME_HUB,0.25f);
|
GameState::ChangeState(States::GAME_HUB,0.25f);
|
||||||
return true;
|
return true;
|
||||||
|
@ -47,6 +47,10 @@ All rights reserved.
|
|||||||
#include "MonsterAttribute.h"
|
#include "MonsterAttribute.h"
|
||||||
#include "ItemDrop.h"
|
#include "ItemDrop.h"
|
||||||
#include "SoundEffect.h"
|
#include "SoundEffect.h"
|
||||||
|
#include "Unlock.h"
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/isteamuserstats.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
INCLUDE_ANIMATION_DATA
|
INCLUDE_ANIMATION_DATA
|
||||||
INCLUDE_MONSTER_DATA
|
INCLUDE_MONSTER_DATA
|
||||||
@ -723,6 +727,27 @@ void Monster::OnDeath(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unlock::IncreaseKillCount();
|
||||||
|
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
for(auto&[key,size]:DATA.GetProperty("Achievement.Kill Unlocks")){
|
||||||
|
//Monster-specific achievement unlocks.
|
||||||
|
datafile&unlock=DATA.GetProperty(std::format("Achievement.Kill Unlocks.{}",key));
|
||||||
|
if(unlock.HasProperty("Monster Name")){
|
||||||
|
if(unlock["Monster Name"].GetString()!=GetName())continue;
|
||||||
|
if(unlock.HasProperty("Time Limit")&&isBoss){
|
||||||
|
if(game->GetEncounterDuration()<=unlock["Time Limit"].GetReal()){
|
||||||
|
SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if(hasStrategyDeathFunction){
|
if(hasStrategyDeathFunction){
|
||||||
GameEvent::AddEvent(std::make_unique<MonsterStrategyGameEvent>(strategyDeathFunc,*this,MONSTER_DATA[name].GetAIStrategy()));
|
GameEvent::AddEvent(std::make_unique<MonsterStrategyGameEvent>(strategyDeathFunc,*this,MONSTER_DATA[name].GetAIStrategy()));
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,9 @@ All rights reserved.
|
|||||||
#include "GameSettings.h"
|
#include "GameSettings.h"
|
||||||
#include "Unlock.h"
|
#include "Unlock.h"
|
||||||
#include "Tutorial.h"
|
#include "Tutorial.h"
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/isteamuserstats.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
INCLUDE_MONSTER_DATA
|
INCLUDE_MONSTER_DATA
|
||||||
INCLUDE_MONSTER_LIST
|
INCLUDE_MONSTER_LIST
|
||||||
@ -777,9 +780,9 @@ void Player::AddAnimation(std::string state){
|
|||||||
animation.AddState(state,ANIMATION_DATA.at(state));
|
animation.AddState(state,ANIMATION_DATA.at(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdateAnimation(std::string animState,int specificClass){
|
void Player::UpdateAnimation(std::string animState,int specificClass, const float frameMult){
|
||||||
if(specificClass==ANY||specificClass&GetClass()){
|
if(specificClass==ANY||specificClass&GetClass()){
|
||||||
animation.ChangeState(internal_animState,animState);
|
animation.ChangeState(internal_animState,animState,frameMult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,7 +871,7 @@ void Player::Spin(float duration,float spinSpd){
|
|||||||
spin_angle=0;
|
spin_angle=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdateWalkingAnimation(Key direction){
|
void Player::UpdateWalkingAnimation(Key direction, const float frameMult){
|
||||||
std::string anim;
|
std::string anim;
|
||||||
switch(direction){
|
switch(direction){
|
||||||
case UP:anim=GetWalkNAnimation();break;
|
case UP:anim=GetWalkNAnimation();break;
|
||||||
@ -876,7 +879,7 @@ void Player::UpdateWalkingAnimation(Key direction){
|
|||||||
case DOWN:anim=GetWalkSAnimation();break;
|
case DOWN:anim=GetWalkSAnimation();break;
|
||||||
case LEFT:anim=GetWalkWAnimation();break;
|
case LEFT:anim=GetWalkWAnimation();break;
|
||||||
}
|
}
|
||||||
UpdateAnimation(anim);
|
UpdateAnimation(anim,0,frameMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdateIdleAnimation(Key direction){
|
void Player::UpdateIdleAnimation(Key direction){
|
||||||
@ -1301,9 +1304,8 @@ void Player::AddXP(const uint32_t xpGain){
|
|||||||
currentLevelXP+=xpGain;
|
currentLevelXP+=xpGain;
|
||||||
totalXPEarned+=xpGain;
|
totalXPEarned+=xpGain;
|
||||||
if(Level()<LevelCap()){
|
if(Level()<LevelCap()){
|
||||||
uint32_t nextLevelXP=NextLevelXPRequired();
|
while(currentLevelXP>=NextLevelXPRequired()){
|
||||||
while(currentLevelXP>=nextLevelXP){
|
currentLevelXP-=NextLevelXPRequired();
|
||||||
currentLevelXP-=nextLevelXP;
|
|
||||||
SetLevel(Level()+1);
|
SetLevel(Level()+1);
|
||||||
OnLevelUp();
|
OnLevelUp();
|
||||||
}
|
}
|
||||||
@ -1324,6 +1326,18 @@ void Player::OnLevelUp(){
|
|||||||
stats.SetBaseStat("Health",GetBaseStat("Health")+hpGrowthRate);
|
stats.SetBaseStat("Health",GetBaseStat("Health")+hpGrowthRate);
|
||||||
stats.SetBaseStat("Attack",GetBaseStat("Attack")+atkGrowthRate);
|
stats.SetBaseStat("Attack",GetBaseStat("Attack")+atkGrowthRate);
|
||||||
Heal(GetBaseStat("Health"));
|
Heal(GetBaseStat("Health"));
|
||||||
|
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
for(auto&[key,size]:DATA.GetProperty("Achievement.Class Unlocks")){
|
||||||
|
datafile&unlock=DATA.GetProperty(std::format("Achievement.Class Unlocks.{}",key));
|
||||||
|
if(classutils::StringToClass(unlock["Class Requirement"].GetString())==GetClass()&&
|
||||||
|
Level()-1<unlock["Level Requirement"].GetInt()&&
|
||||||
|
Level()==unlock["Level Requirement"].GetInt()){
|
||||||
|
SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
const uint8_t Player::LevelCap()const{
|
const uint8_t Player::LevelCap()const{
|
||||||
return levelCap;
|
return levelCap;
|
||||||
@ -1429,17 +1443,18 @@ const vf2d Player::GetAimingLocation(bool useWalkDir,bool invert){
|
|||||||
vf2d closestPoint={std::numeric_limits<float>::max(),std::numeric_limits<float>::max()};
|
vf2d closestPoint={std::numeric_limits<float>::max(),std::numeric_limits<float>::max()};
|
||||||
for(Monster&m:MONSTER_LIST){
|
for(Monster&m:MONSTER_LIST){
|
||||||
if(m.IsAlive()){
|
if(m.IsAlive()){
|
||||||
float distToMonster=geom2d::line<float>(GetPos(),m.GetPos()).length();
|
|
||||||
geom2d::line<float>aimingLine=geom2d::line<float>(GetPos(),m.GetPos());
|
geom2d::line<float>aimingLine=geom2d::line<float>(GetPos(),m.GetPos());
|
||||||
vf2d aimingPoint=aimingLine.rpoint((invert?-1.f:1.f)*operator""_Pixels("Player.Aiming Cursor Max Distance"_F));
|
float distToMonster=aimingLine.length();
|
||||||
float distToClosestPoint=geom2d::line<float>(GetPos(),closestPoint).length();
|
float distToClosestPoint=geom2d::line<float>(GetPos(),closestPoint).length();
|
||||||
if(distToClosestPoint>distToMonster&&distToMonster<=operator""_Pixels("Player.Auto Aim Detection Distance"_F)){
|
if(distToClosestPoint>distToMonster&&distToMonster<=operator""_Pixels("Player.Auto Aim Detection Distance"_F)){
|
||||||
closestPoint=aimingPoint;
|
closestPoint=m.GetPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(closestPoint!=vf2d{std::numeric_limits<float>::max(),std::numeric_limits<float>::max()}){
|
if(closestPoint!=vf2d{std::numeric_limits<float>::max(),std::numeric_limits<float>::max()}){
|
||||||
return game->GetScreenSize()/2+closestPoint-GetPos();
|
geom2d::line<float>aimingLine=geom2d::line<float>(GetPos(),closestPoint);
|
||||||
|
vf2d aimingPoint=aimingLine.rpoint(invert?(-operator""_Pixels("Player.Aiming Cursor Max Distance"_F)):std::min(aimingLine.length()+24.f,float(operator""_Pixels("Player.Aiming Cursor Max Distance"_F))));
|
||||||
|
return game->GetScreenSize()/2+aimingPoint-GetPos();
|
||||||
}else
|
}else
|
||||||
return game->GetScreenSize()/2+vf2d{float(operator""_Pixels("Player.Aiming Cursor Max Distance"_F)),aimingAngle.y}.cart();
|
return game->GetScreenSize()/2+vf2d{float(operator""_Pixels("Player.Aiming Cursor Max Distance"_F)),aimingAngle.y}.cart();
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ public:
|
|||||||
vf2d GetVelocity();
|
vf2d GetVelocity();
|
||||||
bool HasIframes();
|
bool HasIframes();
|
||||||
void Update(float fElapsedTime);
|
void Update(float fElapsedTime);
|
||||||
void UpdateWalkingAnimation(Key direction);
|
void UpdateWalkingAnimation(Key direction, const float frameMult=1.f);
|
||||||
void UpdateIdleAnimation(Key direction);
|
void UpdateIdleAnimation(Key direction);
|
||||||
//The range is the search range in tiles.
|
//The range is the search range in tiles.
|
||||||
bool CanPathfindTo(vf2d pos,vf2d targetPos,float range=8);
|
bool CanPathfindTo(vf2d pos,vf2d targetPos,float range=8);
|
||||||
@ -176,9 +176,8 @@ public:
|
|||||||
bool Hurt(int damage,bool onUpperLevel,float z);
|
bool Hurt(int damage,bool onUpperLevel,float z);
|
||||||
//Return false if healing was not possible.
|
//Return false if healing was not possible.
|
||||||
bool Heal(int damage,bool suppressDamageNumber=false);
|
bool Heal(int damage,bool suppressDamageNumber=false);
|
||||||
//specificClass is a bitwise-combination of classes from the Class enum. It makes sure certain animations only play if you are a certain class.
|
//specificClass is a bitwise-combination of classes from the Class enum. It makes sure certain animations only play if you are a certain class.=
|
||||||
//Set force to true to force the animation to restart evne if the animation were already playing.
|
void UpdateAnimation(std::string animState,int specificClass=ANY,const float frameMult=1.f);
|
||||||
void UpdateAnimation(std::string animState,int specificClass=ANY);
|
|
||||||
Animate2D::Frame GetFrame();
|
Animate2D::Frame GetFrame();
|
||||||
Key GetLastReleasedMovementKey();
|
Key GetLastReleasedMovementKey();
|
||||||
float GetSwordSwingTimer();
|
float GetSwordSwingTimer();
|
||||||
|
@ -178,7 +178,14 @@ const void SaveFile::SaveGame(){
|
|||||||
saveSystemFile["Fullscreen"].SetBool(game->IsFullscreen());
|
saveSystemFile["Fullscreen"].SetBool(game->IsFullscreen());
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
saveFile["Hash"].SetString("");
|
||||||
|
|
||||||
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
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(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){
|
||||||
@ -279,6 +286,24 @@ void SaveFile::LoadFile(){
|
|||||||
|
|
||||||
if(std::filesystem::exists(loadFilename)){
|
if(std::filesystem::exists(loadFilename)){
|
||||||
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||||
|
if(!loadFile.HasProperty("Hash")){
|
||||||
|
LOG(std::format("WARNING! Filehash for file {} does not exist!","save_file_path"_S+std::format("save.{:04}",saveFileID)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(loadFile.HasProperty("Hash")){
|
||||||
|
std::string expectedFileHash=loadFile["Hash"].GetString();
|
||||||
|
loadFile["Hash"].SetString("");
|
||||||
|
utils::datafile::Write(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||||
|
std::string fileHash=util::GetHash("save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||||
|
|
||||||
|
if(expectedFileHash!=fileHash){
|
||||||
|
LOG(std::format("WARNING! Filehash for file {} was not identified as proper! Will not load this file!","save_file_path"_S+std::format("save.{:04}",saveFileID)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFile["Hash"].SetString(expectedFileHash); //Now write the hash back into the file since we tampered with it.
|
||||||
|
utils::datafile::Write(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||||
|
}
|
||||||
game->ResetGame();
|
game->ResetGame();
|
||||||
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
|
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
|
||||||
std::weak_ptr<Item>newItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt());
|
std::weak_ptr<Item>newItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt());
|
||||||
|
@ -41,6 +41,7 @@ All rights reserved.
|
|||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
#include "AdventuresInLestoria.h"
|
#include "AdventuresInLestoria.h"
|
||||||
#include "Unlock.h"
|
#include "Unlock.h"
|
||||||
|
#include "MenuLabel.h"
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
|
|
||||||
@ -48,7 +49,9 @@ void Menu::InitializeShermanWindow(){
|
|||||||
Menu*shermanWindow=CreateMenu(SHERMAN,CENTERED,vi2d{144,88});
|
Menu*shermanWindow=CreateMenu(SHERMAN,CENTERED,vi2d{144,88});
|
||||||
|
|
||||||
shermanWindow->ADD("Leave Button",MenuComponent)(geom2d::rect<float>{{0.f,4.f},{144.f,24.f}},"Leave",[](MenuFuncData data){
|
shermanWindow->ADD("Leave Button",MenuComponent)(geom2d::rect<float>{{0.f,4.f},{144.f,24.f}},"Leave",[](MenuFuncData data){
|
||||||
|
if(Component<MenuLabel>(LEVEL_COMPLETE,"Stage Complete Label")->GetLabel()!="Stage Summary"){ //If the label says stage summary, we didn't actually complete the level. Don't unlock anything new for the player.
|
||||||
Unlock::UnlockCurrentMap();
|
Unlock::UnlockCurrentMap();
|
||||||
|
}
|
||||||
GameState::ChangeState(States::OVERWORLD_MAP,0.3f);
|
GameState::ChangeState(States::OVERWORLD_MAP,0.3f);
|
||||||
return true;
|
return true;
|
||||||
},vf2d{2.f,2.f},ButtonAttr::FIT_TO_LABEL)END;
|
},vf2d{2.f,2.f},ButtonAttr::FIT_TO_LABEL)END;
|
||||||
|
@ -77,6 +77,7 @@ void State_GameHub::OnLevelLoad(){
|
|||||||
}
|
}
|
||||||
void State_GameHub::OnUserUpdate(AiL*game){
|
void State_GameHub::OnUserUpdate(AiL*game){
|
||||||
State_GameRun::OnUserUpdate(game);
|
State_GameRun::OnUserUpdate(game);
|
||||||
|
|
||||||
game->ClearTimedOutGarbage();
|
game->ClearTimedOutGarbage();
|
||||||
}
|
}
|
||||||
void State_GameHub::Draw(AiL*game){
|
void State_GameHub::Draw(AiL*game){
|
||||||
|
@ -42,6 +42,9 @@ All rights reserved.
|
|||||||
#include "Key.h"
|
#include "Key.h"
|
||||||
#include "ItemDrop.h"
|
#include "ItemDrop.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/isteamuserstats.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
|
|
||||||
|
54
Adventures in Lestoria/SteamStatsReceivedHandler.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#pragma region License
|
||||||
|
/*
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||||||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||||||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without specific
|
||||||
|
prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
Portions of this software are copyright © 2024 The FreeType
|
||||||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
#pragma endregion
|
||||||
|
#include "SteamStatsReceivedHandler.h"
|
||||||
|
#include "olcUTIL_DataFile.h"
|
||||||
|
#include "DEFINES.h"
|
||||||
|
#include "Unlock.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
INCLUDE_DATA
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
void SteamStatsReceivedHandler::SteamStatsReceived( UserStatsReceived_t* pCallback ){
|
||||||
|
if(pCallback->m_eResult==k_EResultOK){
|
||||||
|
SteamUserStats()->GetStat("Achievement.Kill Unlocks.Total Kill API Name"_S.c_str(),&Unlock::monsterKillCount);
|
||||||
|
LOG(std::format("Retrieved monster kill count: {}",Unlock::monsterKillCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
47
Adventures in Lestoria/SteamStatsReceivedHandler.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma region License
|
||||||
|
/*
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||||||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||||||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without specific
|
||||||
|
prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
Portions of this software are copyright © 2024 The FreeType
|
||||||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
#pragma endregion
|
||||||
|
#pragma once
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/steam_api.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
class SteamStatsReceivedHandler{
|
||||||
|
STEAM_CALLBACK(SteamStatsReceivedHandler,SteamStatsReceived,UserStatsReceived_t);
|
||||||
|
};
|
||||||
|
#endif
|
@ -44,6 +44,8 @@ All rights reserved.
|
|||||||
#include "DEFINES.h"
|
#include "DEFINES.h"
|
||||||
#include "safemap.h"
|
#include "safemap.h"
|
||||||
#include "ItemMapData.h"
|
#include "ItemMapData.h"
|
||||||
|
#include "Class.h"
|
||||||
|
|
||||||
|
|
||||||
using MapName=std::string;
|
using MapName=std::string;
|
||||||
using namespace olc;
|
using namespace olc;
|
||||||
@ -126,6 +128,7 @@ private:
|
|||||||
std::vector<NPCData>npcs;
|
std::vector<NPCData>npcs;
|
||||||
std::string mapType="";
|
std::string mapType="";
|
||||||
std::string bgmSongName="";
|
std::string bgmSongName="";
|
||||||
|
std::unordered_map<Class,float>devCompletionTrialTime;
|
||||||
BackdropName backdrop="";
|
BackdropName backdrop="";
|
||||||
std::set<std::string>spawns;
|
std::set<std::string>spawns;
|
||||||
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
|
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
|
||||||
@ -138,6 +141,7 @@ public:
|
|||||||
const std::vector<ItemMapData>&GetStageLoot()const;
|
const std::vector<ItemMapData>&GetStageLoot()const;
|
||||||
const std::vector<LayerTag>&GetLayers()const;
|
const std::vector<LayerTag>&GetLayers()const;
|
||||||
const std::vector<EnvironmentalAudio>&GetEnvironmentalAudio()const;
|
const std::vector<EnvironmentalAudio>&GetEnvironmentalAudio()const;
|
||||||
|
const float GetDevCompletionTime(Class cl)const;
|
||||||
const MapName&GetMapName()const;
|
const MapName&GetMapName()const;
|
||||||
const std::string_view GetMapDisplayName()const;
|
const std::string_view GetMapDisplayName()const;
|
||||||
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles);
|
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles);
|
||||||
@ -464,6 +468,13 @@ class TMXParser{
|
|||||||
parsedMapInfo.bgmSongName=newTag.data["value"];
|
parsedMapInfo.bgmSongName=newTag.data["value"];
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
if (newTag.tag=="property"&&newTag.data["name"].starts_with("Dev Completion Time")) {
|
||||||
|
if(newTag.data.count("value")){ //None is a default value that we ignore.
|
||||||
|
size_t classStartPos="Dev Completion Time - "s.length();
|
||||||
|
std::string className=newTag.data["name"].substr(classStartPos,newTag.data["name"].find(' ',classStartPos)-classStartPos);
|
||||||
|
parsedMapInfo.devCompletionTrialTime[classutils::StringToClass(className)]=newTag.GetFloat("value");
|
||||||
|
}
|
||||||
|
} else
|
||||||
if (newTag.tag=="property"&&newTag.data["name"]=="Backdrop") {
|
if (newTag.tag=="property"&&newTag.data["name"]=="Backdrop") {
|
||||||
if(newTag.data["value"]!="None"){ //None is a default value that we ignore.
|
if(newTag.data["value"]!="None"){ //None is a default value that we ignore.
|
||||||
parsedMapInfo.backdrop=newTag.data["value"];
|
parsedMapInfo.backdrop=newTag.data["value"];
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
============================================
|
Time Trial Idea
|
||||||
|
|
||||||
|
Upon completing a stage for the first time, the player is shown the completion time and a record time.
|
||||||
|
On first clears, the player will always obtain a new record. Make it apparent to the player they obtained a new record.
|
||||||
|
|
||||||
|
The overworld map will show a new section that says "Completion Time" for any previous completed stages.
|
||||||
|
Upon the second time entering a stage, the game will spawn a timer that the player can run into to begin a time trial-like mode.
|
||||||
|
During the Time Trial mode the player can defeat monsters to freeze the timer by 1 second per mob killed.
|
||||||
|
|
||||||
|
Upon completion of a stage in time trial mode if the player beat their previous time (which they likely will) the record will update.
|
||||||
|
For each class and stage combination there will be a "dev time"
|
||||||
|
|
||||||
|
Settings menu doesn't scroll back up properly while the scrollbar does?
|
||||||
|
Merchant descriptions have no newlines.
|
||||||
|
|
||||||
|
============================================
|
||||||
|
Consider a "killed by player" / "marked by player" flag for monsters to determine if a player gets credit for a monster kill (for achievements)
|
||||||
Make another actions config file for the main build (The app # is different)
|
Make another actions config file for the main build (The app # is different)
|
@ -38,16 +38,33 @@ All rights reserved.
|
|||||||
#include "Unlock.h"
|
#include "Unlock.h"
|
||||||
#include "State_OverworldMap.h"
|
#include "State_OverworldMap.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "olcUTIL_DataFile.h"
|
||||||
|
#include "DEFINES.h"
|
||||||
|
#include "emscripten_compat.h"
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#include "steam/isteamuserstats.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INCLUDE_DATA
|
||||||
|
|
||||||
std::set<std::string>Unlock::unlocks;
|
std::set<std::string>Unlock::unlocks;
|
||||||
|
int Unlock::monsterKillCount=0;
|
||||||
|
|
||||||
void Unlock::Initialize(){
|
void Unlock::Initialize(){
|
||||||
|
unlocks.clear();
|
||||||
UnlockArea("WORLD_MAP");
|
UnlockArea("WORLD_MAP");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unlock::UnlockArea(std::string mapName){
|
void Unlock::UnlockArea(std::string mapName){
|
||||||
if(mapName=="NPCs.Sherman.Potion Crafting Unlock Condition"_S&& //When we beat the bonus chapter 1 fight, before sherman's potion crafting is unlocked, if the current map we just unlocked for is the bonus boss stage we will notify the Hub connection point and reset it so the player has a notification to go there again.
|
if(mapName=="NPCs.Sherman.Potion Crafting Unlock Condition"_S&& //When we beat the bonus chapter 1 fight, before sherman's potion crafting is unlocked, if the current map we just unlocked for is the bonus boss stage we will notify the Hub connection point and reset it so the player has a notification to go there again.
|
||||||
!Unlock::IsUnlocked("NPCs.Sherman.Potion Crafting Unlock Condition"_S))State_OverworldMap::ConnectionPointFromString("HUB").value()->ResetVisitedFlag();
|
!Unlock::IsUnlocked("NPCs.Sherman.Potion Crafting Unlock Condition"_S))State_OverworldMap::ConnectionPointFromString("HUB").value()->ResetVisitedFlag();
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
datafile&areaUnlocks=DATA.GetProperty("Achievement.Area Unlocks");
|
||||||
|
for(auto&[key,size]:areaUnlocks){
|
||||||
|
datafile&unlock = areaUnlocks[key];
|
||||||
|
if(mapName==unlock["Unlock Name"].GetString())SteamUserStats()->SetAchievement(unlock["API Name"].GetString().c_str());
|
||||||
|
}
|
||||||
|
)
|
||||||
unlocks.insert(mapName);
|
unlocks.insert(mapName);
|
||||||
}
|
}
|
||||||
bool Unlock::IsUnlocked(std::string mapName){
|
bool Unlock::IsUnlocked(std::string mapName){
|
||||||
@ -61,3 +78,20 @@ bool Unlock::IsUnlocked(ConnectionPoint&cp){
|
|||||||
void Unlock::UnlockCurrentMap(){
|
void Unlock::UnlockCurrentMap(){
|
||||||
UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
|
UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unlock::IncreaseKillCount(){
|
||||||
|
monsterKillCount++;
|
||||||
|
STEAMUSERSTATS(
|
||||||
|
SteamUserStats()->SetStat("Achievement.Kill Unlocks.Total Kill API Name"_S.c_str(),Unlock::monsterKillCount);
|
||||||
|
datafile&killUnlocks=DATA.GetProperty("Achievement.Kill Unlocks");
|
||||||
|
for(auto&[key,size]:killUnlocks){
|
||||||
|
if(key.starts_with("Kill Monsters")){
|
||||||
|
int killRequirement=killUnlocks[key]["Monster Kill Count"].GetInt();
|
||||||
|
if(monsterKillCount-1<killRequirement&& //These two checks make sure we've just reached the kill requirement, so we can send a more readily live update for the player.
|
||||||
|
monsterKillCount==killRequirement){
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
@ -43,8 +43,10 @@ All rights reserved.
|
|||||||
class Unlock{
|
class Unlock{
|
||||||
friend class AiL;
|
friend class AiL;
|
||||||
friend class SaveFile;
|
friend class SaveFile;
|
||||||
|
friend class SteamStatsReceivedHandler;
|
||||||
static std::set<std::string>unlocks;
|
static std::set<std::string>unlocks;
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
|
static int monsterKillCount;
|
||||||
public:
|
public:
|
||||||
//Provide a map's actual name to trigger unlocks for all connected areas. You can get the current map you are on via State_OverworldMap::GetCurrentConnectionPoint().map
|
//Provide a map's actual name to trigger unlocks for all connected areas. You can get the current map you are on via State_OverworldMap::GetCurrentConnectionPoint().map
|
||||||
static void UnlockArea(std::string mapName);
|
static void UnlockArea(std::string mapName);
|
||||||
@ -52,4 +54,5 @@ public:
|
|||||||
static void UnlockCurrentMap();
|
static void UnlockCurrentMap();
|
||||||
static bool IsUnlocked(std::string mapName);
|
static bool IsUnlocked(std::string mapName);
|
||||||
static bool IsUnlocked(ConnectionPoint&cp);
|
static bool IsUnlocked(ConnectionPoint&cp);
|
||||||
|
static void IncreaseKillCount();
|
||||||
};
|
};
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 8477
|
#define VERSION_BUILD 8598
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
BIN
Adventures in Lestoria/assets/Achievements/BronzeBorder.xcf
Normal file
BIN
Adventures in Lestoria/assets/Achievements/GoldBorder.xcf
Normal file
BIN
Adventures in Lestoria/assets/Achievements/SilverBorder.xcf
Normal file
BIN
Adventures in Lestoria/assets/Achievements/armor_10.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Adventures in Lestoria/assets/Achievements/armor_10_locked.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
Adventures in Lestoria/assets/Achievements/armor_5.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Adventures in Lestoria/assets/Achievements/armor_5_locked.png
Normal file
After Width: | Height: | Size: 101 KiB |
BIN
Adventures in Lestoria/assets/Achievements/blacksmith_unlock.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
BIN
Adventures in Lestoria/assets/Achievements/camp_unlock.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 104 KiB |
BIN
Adventures in Lestoria/assets/Achievements/chapter1_complete.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 103 KiB |
BIN
Adventures in Lestoria/assets/Achievements/fully_decked_out.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 104 KiB |
BIN
Adventures in Lestoria/assets/Achievements/kill_slime_1.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 155 KiB |
BIN
Adventures in Lestoria/assets/Achievements/kill_slime_2.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 168 KiB |
BIN
Adventures in Lestoria/assets/Achievements/kill_slime_3.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 127 KiB |
BIN
Adventures in Lestoria/assets/Achievements/ranger_level5.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 120 KiB |
BIN
Adventures in Lestoria/assets/Achievements/slime_king.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 92 KiB |
BIN
Adventures in Lestoria/assets/Achievements/slime_king_locked.png
Normal file
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 88 KiB |
BIN
Adventures in Lestoria/assets/Achievements/ursule_unlock.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 101 KiB |
BIN
Adventures in Lestoria/assets/Achievements/warrior_level5.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 117 KiB |
BIN
Adventures in Lestoria/assets/Achievements/weapon_5.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Adventures in Lestoria/assets/Achievements/weapon_5_locked.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
Adventures in Lestoria/assets/Achievements/wizard_level5.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 64 KiB |
@ -1,8 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="205" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="11" nextobjectid="179">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="205" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="11" nextobjectid="507">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
|
<property name="Dev Completion Time - Ranger (s)" type="float" value="120"/>
|
||||||
|
<property name="Dev Completion Time - Warrior (s)" type="float" value="120"/>
|
||||||
|
<property name="Dev Completion Time - Wizard (s)" type="float" value="120"/>
|
||||||
<property name="Level Type" propertytype="LevelType" value="Dungeon"/>
|
<property name="Level Type" propertytype="LevelType" value="Dungeon"/>
|
||||||
</properties>
|
</properties>
|
||||||
<tileset firstgid="1" source="../maps/Tilesheet_No_Shadow24x24.tsx"/>
|
<tileset firstgid="1" source="../maps/Tilesheet_No_Shadow24x24.tsx"/>
|
||||||
@ -2009,5 +2012,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="180" name="Time Trial Clock" type="TrialClock" x="624" y="4224" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="122" tilewidth="24" tileheight="24" infinite="0" nextlayerid="9" nextobjectid="82">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="122" tilewidth="24" tileheight="24" infinite="0" nextlayerid="9" nextobjectid="83">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -845,5 +845,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="82" name="Time Trial Clock" type="TrialClock" x="3648" y="648" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="205" height="250" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="97">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="205" height="250" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="98">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -1551,6 +1551,7 @@
|
|||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
<object id="95" name="End Zone" type="EndZone" x="1726" y="1681" width="72" height="72"/>
|
<object id="95" name="End Zone" type="EndZone" x="1726" y="1681" width="72" height="72"/>
|
||||||
|
<object id="97" name="Time Trial Clock" type="TrialClock" x="1656" y="5448" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
<objectgroup id="7" name="Environmental Sounds">
|
<objectgroup id="7" name="Environmental Sounds">
|
||||||
<object id="30" name="Waterfall Sound" type="AudioEnvironmentalSound" x="4313" y="2678">
|
<object id="30" name="Waterfall Sound" type="AudioEnvironmentalSound" x="4313" y="2678">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="250" height="175" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="107">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="250" height="175" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="108">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -1154,5 +1154,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="107" name="Time Trial Clock" type="TrialClock" x="720" y="3456" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="229" height="155" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="84">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="229" height="155" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="85">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -1118,6 +1118,7 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="84" name="Time Trial Clock" type="TrialClock" x="1824" y="408" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
<objectgroup id="7" name="Environmental Sounds">
|
<objectgroup id="7" name="Environmental Sounds">
|
||||||
<object id="24" name="Waterfall Sound" type="AudioEnvironmentalSound" x="3425" y="264">
|
<object id="24" name="Waterfall Sound" type="AudioEnvironmentalSound" x="3425" y="264">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="250" height="127" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="87">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="250" height="127" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="88">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -893,5 +893,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="87" name="Time Trial Clock" type="TrialClock" x="360" y="1488" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="148" height="131" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="68">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="148" height="131" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="69">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -796,5 +796,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="68" name="Time Trial Clock" type="TrialClock" x="96" y="312" width="24" height="24"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="72" height="80" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="9">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="72" height="80" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="9">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty_boss"/>
|
<property name="Background Music" propertytype="BGM" value="foresty_boss"/>
|
||||||
|
118
Adventures in Lestoria/assets/config/Achievements.txt
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
Achievement
|
||||||
|
{
|
||||||
|
Area Unlocks
|
||||||
|
{
|
||||||
|
# Area Unlocks are automatically checked when a new map unlock is achieved.
|
||||||
|
Camp Unlock
|
||||||
|
{
|
||||||
|
API Name = "CAMP_UNLOCK"
|
||||||
|
Unlock Name = "STORY_1_1"
|
||||||
|
}
|
||||||
|
Blacksmith Unlock
|
||||||
|
{
|
||||||
|
API Name = "BLACKSMITH_UNLOCK"
|
||||||
|
Unlock Name = "STORY_1_2"
|
||||||
|
}
|
||||||
|
Chapter 2 Unlock
|
||||||
|
{
|
||||||
|
API Name = "CHAPTER1_COMPLETE"
|
||||||
|
Unlock Name = "STORY_1_3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kill Unlocks
|
||||||
|
{
|
||||||
|
Total Kill API Name = "MONSTER_KILL_COUNT"
|
||||||
|
|
||||||
|
# Achievements that start with "Kill Monsters" will be checked when a monster is killed.
|
||||||
|
Kill Monsters 1
|
||||||
|
{
|
||||||
|
API Name = "KILL_SLIME_1"
|
||||||
|
Monster Kill Count = 100
|
||||||
|
}
|
||||||
|
Kill Monsters 2
|
||||||
|
{
|
||||||
|
API Name = "KILL_SLIME_2"
|
||||||
|
Monster Kill Count = 250
|
||||||
|
}
|
||||||
|
Kill Monsters 3
|
||||||
|
{
|
||||||
|
API Name = "KILL_SLIME_3"
|
||||||
|
Monster Kill Count = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
##################################
|
||||||
|
|
||||||
|
# For other Kill Encounter achievements, if they have a Monster Name the game looks for the name when a monster is killed and if it matches, you get awarded that achievement.
|
||||||
|
# If a Time Limit is included, the encounter must be a boss encounter and
|
||||||
|
Slime King
|
||||||
|
{
|
||||||
|
API Name = "SLIME_KING"
|
||||||
|
Monster Name = "Slime King"
|
||||||
|
}
|
||||||
|
Slime King Destroyer
|
||||||
|
{
|
||||||
|
API Name = "SLIME_KING_DESTROYER"
|
||||||
|
Time Limit = 60s
|
||||||
|
Monster Name = "Slime King"
|
||||||
|
}
|
||||||
|
Ursule
|
||||||
|
{
|
||||||
|
API Name = "URSULE"
|
||||||
|
Monster Name = "Ursule, Mother of Bears"
|
||||||
|
}
|
||||||
|
Ursule Destroyer
|
||||||
|
{
|
||||||
|
API Name = "URSULE_DESTROYER"
|
||||||
|
Time Limit = 60s
|
||||||
|
Monster Name = "Ursule, Mother of Bears"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Class Unlocks
|
||||||
|
{
|
||||||
|
Warrior Lv5
|
||||||
|
{
|
||||||
|
API Name = "WARRIOR_LV5"
|
||||||
|
Class Requirement = Warrior
|
||||||
|
Level Requirement = 5
|
||||||
|
}
|
||||||
|
Ranger Lv5
|
||||||
|
{
|
||||||
|
API Name = "RANGER_LV5"
|
||||||
|
Class Requirement = Ranger
|
||||||
|
Level Requirement = 5
|
||||||
|
}
|
||||||
|
Wizard Lv5
|
||||||
|
{
|
||||||
|
API Name = "WIZARD_LV5"
|
||||||
|
Class Requirement = Wizard
|
||||||
|
Level Requirement = 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Equip Unlocks
|
||||||
|
{
|
||||||
|
Weapon Lv5
|
||||||
|
{
|
||||||
|
API Name = "WEAPON_LV5"
|
||||||
|
Equip Slot = Weapon
|
||||||
|
Upgrade Requirement = 5
|
||||||
|
}
|
||||||
|
Armor Lv5
|
||||||
|
{
|
||||||
|
API Name = "ARMOR_LV5"
|
||||||
|
Equip Slot = Helmet,Armor,Gloves,Pants,Shoes
|
||||||
|
Upgrade Requirement = 5
|
||||||
|
}
|
||||||
|
Armor Lv10
|
||||||
|
{
|
||||||
|
API Name = "ARMOR_LV10"
|
||||||
|
Equip Slot = Helmet,Armor,Gloves,Pants,Shoes
|
||||||
|
Upgrade Requirement = 10
|
||||||
|
}
|
||||||
|
Fully Decked Out
|
||||||
|
{
|
||||||
|
API Name = "FULLY_DECKED_OUT"
|
||||||
|
Weapon Max Level = 5
|
||||||
|
Armor Max Level = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,9 @@ Player
|
|||||||
# Amount of spd to increase/decrease vertically as you climb staircases
|
# Amount of spd to increase/decrease vertically as you climb staircases
|
||||||
StaircaseClimbSpd = 45
|
StaircaseClimbSpd = 45
|
||||||
|
|
||||||
|
# Walking Default Animation Delay per Frame
|
||||||
|
WalkingFrameSpd = 0.2s
|
||||||
|
|
||||||
# How much speed the player loses while no momentum is being added.
|
# How much speed the player loses while no momentum is being added.
|
||||||
Friction = 400
|
Friction = 400
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ player_config = Player.txt
|
|||||||
# Monster Properties Loading Config
|
# Monster Properties Loading Config
|
||||||
monsters_config = Monsters.txt
|
monsters_config = Monsters.txt
|
||||||
|
|
||||||
|
# Achievement Config
|
||||||
|
achievement_config = Achievements.txt
|
||||||
|
|
||||||
# NPC Loading Config
|
# NPC Loading Config
|
||||||
npc_config = NPCs.txt
|
npc_config = NPCs.txt
|
||||||
|
|
||||||
|
@ -192,4 +192,9 @@ ItemDatabase
|
|||||||
ItemCategory = Materials
|
ItemCategory = Materials
|
||||||
SellValue = 180
|
SellValue = 180
|
||||||
}
|
}
|
||||||
|
Time Medal
|
||||||
|
{
|
||||||
|
Description = A medal provided to top athletes in Lestoria commemorating a huge victory.
|
||||||
|
ItemCategory = Materials
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BIN
Adventures in Lestoria/assets/items/Time Medal.png
Normal file
After Width: | Height: | Size: 949 B |
@ -1,18 +1,18 @@
|
|||||||
"controller_mappings"
|
"controller_mappings"
|
||||||
{
|
{
|
||||||
"version" "3"
|
"version" "3"
|
||||||
"revision" "82"
|
"revision" "87"
|
||||||
"title" "#Title_Config"
|
"title" "Generic Gamepad"
|
||||||
"description" "#Description_Config"
|
"description" "Default Generic Gamepad controls"
|
||||||
"creator" "76561198025675819"
|
"creator" "76561198025675819"
|
||||||
"progenitor" ""
|
"progenitor" ""
|
||||||
"url" "usercloud://2895980/generic gamepad_3"
|
"url" "autosave://C:\\Program Files (x86)\\Steam\\steamapps\\common\\Steam Controller Configs\\65410091\\config\\2895980\\controller_generic.vdf"
|
||||||
"export_type" "personal_cloud"
|
"export_type" "personal_local"
|
||||||
"controller_type" "controller_generic"
|
"controller_type" "controller_generic"
|
||||||
"controller_caps" "1573375"
|
"controller_caps" "1573375"
|
||||||
"major_revision" "0"
|
"major_revision" "0"
|
||||||
"minor_revision" "0"
|
"minor_revision" "0"
|
||||||
"Timestamp" "1711341077"
|
"Timestamp" "1711752971"
|
||||||
"actions"
|
"actions"
|
||||||
{
|
{
|
||||||
"InGameControls"
|
"InGameControls"
|
||||||
@ -21,6 +21,11 @@
|
|||||||
"legacy_set" "0"
|
"legacy_set" "0"
|
||||||
"StickPadGyro"
|
"StickPadGyro"
|
||||||
{
|
{
|
||||||
|
"Move"
|
||||||
|
{
|
||||||
|
"title" "#Move"
|
||||||
|
"input_mode" "joystick_move"
|
||||||
|
}
|
||||||
"Scroll"
|
"Scroll"
|
||||||
{
|
{
|
||||||
"title" "#Scroll"
|
"title" "#Scroll"
|
||||||
@ -66,8 +71,8 @@
|
|||||||
{
|
{
|
||||||
"english"
|
"english"
|
||||||
{
|
{
|
||||||
"Title_Config" "Generic Gamepad"
|
"Title_Config" "Adventures in Lestoria Configuration"
|
||||||
"Description_Config" "Generic gamepad configuration."
|
"Description_Config" "The default control set for Adventures in Lestoria."
|
||||||
"Set_Ingame" "Gameplay Controls"
|
"Set_Ingame" "Gameplay Controls"
|
||||||
"BasicAttack" "Basic Attack"
|
"BasicAttack" "Basic Attack"
|
||||||
"Defensive" "Use Defensive"
|
"Defensive" "Use Defensive"
|
||||||
@ -84,6 +89,7 @@
|
|||||||
"Function1" "Menu Function 1"
|
"Function1" "Menu Function 1"
|
||||||
"Function2" "Menu Function 2"
|
"Function2" "Menu Function 2"
|
||||||
"Menu" "Menu/Pause"
|
"Menu" "Menu/Pause"
|
||||||
|
"Move" "Move"
|
||||||
"Up" "Up"
|
"Up" "Up"
|
||||||
"Down" "Down"
|
"Down" "Down"
|
||||||
"Left" "Left"
|
"Left" "Left"
|
||||||
@ -614,6 +620,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"group"
|
"group"
|
||||||
|
{
|
||||||
|
"id" "24"
|
||||||
|
"mode" "joystick_move"
|
||||||
|
"name" ""
|
||||||
|
"description" ""
|
||||||
|
"inputs"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
"settings"
|
||||||
|
{
|
||||||
|
"virtual_mode" "1"
|
||||||
|
}
|
||||||
|
"gameactions"
|
||||||
|
{
|
||||||
|
"InGameControls" "Move"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"group"
|
||||||
{
|
{
|
||||||
"id" "0"
|
"id" "0"
|
||||||
"mode" "switches"
|
"mode" "switches"
|
||||||
@ -761,7 +785,8 @@
|
|||||||
"2" "left_trigger active"
|
"2" "left_trigger active"
|
||||||
"3" "right_trigger active"
|
"3" "right_trigger active"
|
||||||
"15" "joystick inactive"
|
"15" "joystick inactive"
|
||||||
"23" "joystick active"
|
"23" "joystick inactive"
|
||||||
|
"24" "joystick active"
|
||||||
"16" "right_joystick inactive"
|
"16" "right_joystick inactive"
|
||||||
"22" "right_joystick active"
|
"22" "right_joystick active"
|
||||||
"14" "dpad inactive"
|
"14" "dpad inactive"
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
"controller_mappings"
|
"controller_mappings"
|
||||||
{
|
{
|
||||||
"version" "3"
|
"version" "3"
|
||||||
"revision" "83"
|
"revision" "85"
|
||||||
"title" "#Title_Config"
|
"title" "Switch Pro"
|
||||||
"description" "#Description_Config"
|
"description" "Default Switch Pro configuration."
|
||||||
"creator" "76561198025675819"
|
"creator" "76561198025675819"
|
||||||
"progenitor" ""
|
"progenitor" ""
|
||||||
"url" "usercloud://2895980/switch pro configuration_0"
|
"url" "autosave://C:\\Program Files (x86)\\Steam\\steamapps\\common\\Steam Controller Configs\\65410091\\config\\2895980\\controller_switch_pro.vdf"
|
||||||
"export_type" "personal_cloud"
|
"export_type" "personal_local"
|
||||||
"controller_type" "controller_switch_pro"
|
"controller_type" "controller_switch_pro"
|
||||||
"controller_caps" "613772287"
|
"controller_caps" "613772287"
|
||||||
"major_revision" "0"
|
"major_revision" "0"
|
||||||
"minor_revision" "0"
|
"minor_revision" "0"
|
||||||
"Timestamp" "1711340749"
|
"Timestamp" "1711752483"
|
||||||
"actions"
|
"actions"
|
||||||
{
|
{
|
||||||
"InGameControls"
|
"InGameControls"
|
||||||
@ -21,6 +21,11 @@
|
|||||||
"legacy_set" "0"
|
"legacy_set" "0"
|
||||||
"StickPadGyro"
|
"StickPadGyro"
|
||||||
{
|
{
|
||||||
|
"Move"
|
||||||
|
{
|
||||||
|
"title" "#Move"
|
||||||
|
"input_mode" "joystick_move"
|
||||||
|
}
|
||||||
"Scroll"
|
"Scroll"
|
||||||
{
|
{
|
||||||
"title" "#Scroll"
|
"title" "#Scroll"
|
||||||
@ -66,8 +71,8 @@
|
|||||||
{
|
{
|
||||||
"english"
|
"english"
|
||||||
{
|
{
|
||||||
"Title_Config" "Switch Pro"
|
"Title_Config" "Adventures in Lestoria Configuration"
|
||||||
"Description_Config" "Nintendo Switch Pro controller configuration."
|
"Description_Config" "The default control set for Adventures in Lestoria."
|
||||||
"Set_Ingame" "Gameplay Controls"
|
"Set_Ingame" "Gameplay Controls"
|
||||||
"BasicAttack" "Basic Attack"
|
"BasicAttack" "Basic Attack"
|
||||||
"Defensive" "Use Defensive"
|
"Defensive" "Use Defensive"
|
||||||
@ -84,6 +89,7 @@
|
|||||||
"Function1" "Menu Function 1"
|
"Function1" "Menu Function 1"
|
||||||
"Function2" "Menu Function 2"
|
"Function2" "Menu Function 2"
|
||||||
"Menu" "Menu/Pause"
|
"Menu" "Menu/Pause"
|
||||||
|
"Move" "Move"
|
||||||
"Up" "Up"
|
"Up" "Up"
|
||||||
"Down" "Down"
|
"Down" "Down"
|
||||||
"Left" "Left"
|
"Left" "Left"
|
||||||
@ -614,6 +620,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"group"
|
"group"
|
||||||
|
{
|
||||||
|
"id" "25"
|
||||||
|
"mode" "joystick_move"
|
||||||
|
"name" ""
|
||||||
|
"description" ""
|
||||||
|
"inputs"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
"settings"
|
||||||
|
{
|
||||||
|
"virtual_mode" "1"
|
||||||
|
}
|
||||||
|
"gameactions"
|
||||||
|
{
|
||||||
|
"InGameControls" "Move"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"group"
|
||||||
{
|
{
|
||||||
"id" "0"
|
"id" "0"
|
||||||
"mode" "switches"
|
"mode" "switches"
|
||||||
@ -761,7 +785,8 @@
|
|||||||
"2" "left_trigger active"
|
"2" "left_trigger active"
|
||||||
"3" "right_trigger active"
|
"3" "right_trigger active"
|
||||||
"15" "joystick inactive"
|
"15" "joystick inactive"
|
||||||
"23" "joystick active"
|
"23" "joystick inactive"
|
||||||
|
"25" "joystick active"
|
||||||
"16" "right_joystick inactive"
|
"16" "right_joystick inactive"
|
||||||
"22" "right_joystick active"
|
"22" "right_joystick active"
|
||||||
"14" "dpad inactive"
|
"14" "dpad inactive"
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
"controller_mappings"
|
"controller_mappings"
|
||||||
{
|
{
|
||||||
"version" "3"
|
"version" "3"
|
||||||
"revision" "76"
|
"revision" "78"
|
||||||
"title" "#Title_Config"
|
"title" "Xbox/Playstation"
|
||||||
"description" "#Description_Config"
|
"description" "Default Xbox/Playstation controls"
|
||||||
"creator" "76561198025675819"
|
"creator" "76561198025675819"
|
||||||
"progenitor" ""
|
"progenitor" ""
|
||||||
"url" "autosave://C:\\Program Files (x86)\\Steam\\steamapps\\common\\Steam Controller Configs\\65410091\\config\\2895980\\controller_xbox360.vdf"
|
"url" "autosave://C:\\Program Files (x86)\\Steam\\steamapps\\common\\Steam Controller Configs\\65410091\\config\\2895980\\controller_xbox360.vdf"
|
||||||
"export_type" "personal_cloud"
|
"export_type" "personal_local"
|
||||||
"controller_type" "controller_xbox360"
|
"controller_type" "controller_xbox360"
|
||||||
"controller_caps" "1590271"
|
"controller_caps" "1590271"
|
||||||
"major_revision" "0"
|
"major_revision" "0"
|
||||||
"minor_revision" "0"
|
"minor_revision" "0"
|
||||||
"Timestamp" "1711340807"
|
"Timestamp" "1711752757"
|
||||||
"actions"
|
"actions"
|
||||||
{
|
{
|
||||||
"InGameControls"
|
"InGameControls"
|
||||||
@ -21,6 +21,11 @@
|
|||||||
"legacy_set" "0"
|
"legacy_set" "0"
|
||||||
"StickPadGyro"
|
"StickPadGyro"
|
||||||
{
|
{
|
||||||
|
"Move"
|
||||||
|
{
|
||||||
|
"title" "#Move"
|
||||||
|
"input_mode" "joystick_move"
|
||||||
|
}
|
||||||
"Scroll"
|
"Scroll"
|
||||||
{
|
{
|
||||||
"title" "#Scroll"
|
"title" "#Scroll"
|
||||||
@ -66,8 +71,8 @@
|
|||||||
{
|
{
|
||||||
"english"
|
"english"
|
||||||
{
|
{
|
||||||
"Title_Config" "Xbox/Playstation"
|
"Title_Config" "Adventures in Lestoria Configuration"
|
||||||
"Description_Config" "Xbox/Playstation controller configuration."
|
"Description_Config" "The default control set for Adventures in Lestoria."
|
||||||
"Set_Ingame" "Gameplay Controls"
|
"Set_Ingame" "Gameplay Controls"
|
||||||
"BasicAttack" "Basic Attack"
|
"BasicAttack" "Basic Attack"
|
||||||
"Defensive" "Use Defensive"
|
"Defensive" "Use Defensive"
|
||||||
@ -84,6 +89,7 @@
|
|||||||
"Function1" "Menu Function 1"
|
"Function1" "Menu Function 1"
|
||||||
"Function2" "Menu Function 2"
|
"Function2" "Menu Function 2"
|
||||||
"Menu" "Menu/Pause"
|
"Menu" "Menu/Pause"
|
||||||
|
"Move" "Move"
|
||||||
"Up" "Up"
|
"Up" "Up"
|
||||||
"Down" "Down"
|
"Down" "Down"
|
||||||
"Left" "Left"
|
"Left" "Left"
|
||||||
@ -614,6 +620,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"group"
|
"group"
|
||||||
|
{
|
||||||
|
"id" "24"
|
||||||
|
"mode" "joystick_move"
|
||||||
|
"name" ""
|
||||||
|
"description" ""
|
||||||
|
"inputs"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
"settings"
|
||||||
|
{
|
||||||
|
"virtual_mode" "1"
|
||||||
|
}
|
||||||
|
"gameactions"
|
||||||
|
{
|
||||||
|
"InGameControls" "Move"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"group"
|
||||||
{
|
{
|
||||||
"id" "0"
|
"id" "0"
|
||||||
"mode" "switches"
|
"mode" "switches"
|
||||||
@ -761,7 +785,8 @@
|
|||||||
"2" "left_trigger active"
|
"2" "left_trigger active"
|
||||||
"3" "right_trigger active"
|
"3" "right_trigger active"
|
||||||
"15" "joystick inactive"
|
"15" "joystick inactive"
|
||||||
"23" "joystick active"
|
"23" "joystick inactive"
|
||||||
|
"24" "joystick active"
|
||||||
"16" "right_joystick inactive"
|
"16" "right_joystick inactive"
|
||||||
"22" "right_joystick active"
|
"22" "right_joystick active"
|
||||||
"14" "dpad inactive"
|
"14" "dpad inactive"
|
@ -7,6 +7,11 @@
|
|||||||
"title" "#Set_Ingame"
|
"title" "#Set_Ingame"
|
||||||
"StickPadGyro"
|
"StickPadGyro"
|
||||||
{
|
{
|
||||||
|
"Move"
|
||||||
|
{
|
||||||
|
"title" "#Move"
|
||||||
|
"input_mode" "joystick_move"
|
||||||
|
}
|
||||||
"Scroll"
|
"Scroll"
|
||||||
{
|
{
|
||||||
"title" "#Scroll"
|
"title" "#Scroll"
|
||||||
@ -64,6 +69,7 @@
|
|||||||
"Function1" "Menu Function 1"
|
"Function1" "Menu Function 1"
|
||||||
"Function2" "Menu Function 2"
|
"Function2" "Menu Function 2"
|
||||||
"Menu" "Menu/Pause"
|
"Menu" "Menu/Pause"
|
||||||
|
"Move" "Move"
|
||||||
"Up" "Up"
|
"Up" "Up"
|
||||||
"Down" "Down"
|
"Down" "Down"
|
||||||
"Left" "Left"
|
"Left" "Left"
|
||||||
@ -79,7 +85,28 @@
|
|||||||
{
|
{
|
||||||
"0"
|
"0"
|
||||||
{
|
{
|
||||||
"path" "controller_xbox360.vdf"
|
"path" "controller_xboxone.vdf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"controller_xboxone"
|
||||||
|
{
|
||||||
|
"0"
|
||||||
|
{
|
||||||
|
"path" "controller_xboxone.vdf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"controller_ps5"
|
||||||
|
{
|
||||||
|
"0"
|
||||||
|
{
|
||||||
|
"path" "controller_xboxone.vdf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"controller_ps4"
|
||||||
|
{
|
||||||
|
"0"
|
||||||
|
{
|
||||||
|
"path" "controller_xboxone.vdf"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"controller_generic"
|
"controller_generic"
|
||||||
|
@ -15,7 +15,9 @@ inline void SteamAPI_RunCallbacks(){};
|
|||||||
|
|
||||||
#define STEAMINPUT(statement) if(false){}
|
#define STEAMINPUT(statement) if(false){}
|
||||||
#define STEAMUTILS(statement) if(false){}
|
#define STEAMUTILS(statement) if(false){}
|
||||||
|
#define STEAMUSERSTATS(statement) if(false){}
|
||||||
#else
|
#else
|
||||||
#define STEAMINPUT(statement) if(SteamInput()){statement}
|
#define STEAMINPUT(statement) if(SteamInput()){statement}
|
||||||
#define STEAMUTILS(statement) if(SteamUtils()){statement}
|
#define STEAMUTILS(statement) if(SteamUtils()){statement}
|
||||||
|
#define STEAMUSERSTATS(statement) if(SteamUserStats()){statement}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4690,7 +4690,15 @@ namespace olc
|
|||||||
{ bHasMouseFocus = state; }
|
{ bHasMouseFocus = state; }
|
||||||
|
|
||||||
void PixelGameEngine::olc_UpdateKeyFocus(bool state)
|
void PixelGameEngine::olc_UpdateKeyFocus(bool state)
|
||||||
{ bHasInputFocus = state; }
|
{
|
||||||
|
if(!state){
|
||||||
|
for (uint32_t i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
olc_UpdateKeyState(i,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bHasInputFocus = state;
|
||||||
|
}
|
||||||
|
|
||||||
void PixelGameEngine::olc_DropFiles(int32_t x, int32_t y, const std::vector<std::string>& vFiles)
|
void PixelGameEngine::olc_DropFiles(int32_t x, int32_t y, const std::vector<std::string>& vFiles)
|
||||||
{
|
{
|
||||||
|
@ -104,6 +104,10 @@ namespace olc::utils::Animate2D
|
|||||||
class FrameSequence
|
class FrameSequence
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Style m_nStyle;
|
||||||
|
std::vector<Frame> m_vFrames;
|
||||||
|
float m_fFrameDuration = 0.1f;
|
||||||
|
float m_fFrameRate = 10.0f;
|
||||||
// Constructs a sequence of frames with a duration and a traversal style
|
// Constructs a sequence of frames with a duration and a traversal style
|
||||||
inline FrameSequence(const float fFrameDuration = 0.1f, const Style nStyle = Style::Repeat)
|
inline FrameSequence(const float fFrameDuration = 0.1f, const Style nStyle = Style::Repeat)
|
||||||
{
|
{
|
||||||
@ -125,10 +129,6 @@ namespace olc::utils::Animate2D
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Style m_nStyle;
|
|
||||||
std::vector<Frame> m_vFrames;
|
|
||||||
float m_fFrameDuration = 0.1f;
|
|
||||||
float m_fFrameRate = 10.0f;
|
|
||||||
|
|
||||||
inline const size_t ConvertTimeToFrame(const float fTime) const
|
inline const size_t ConvertTimeToFrame(const float fTime) const
|
||||||
{
|
{
|
||||||
@ -170,7 +170,13 @@ namespace olc::utils::Animate2D
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Animation() = default;
|
Animation() = default;
|
||||||
|
float mult = 1.f;
|
||||||
|
|
||||||
|
inline bool ChangeState(AnimationState& state, const StatesEnum& sStateName, const float frameMult)
|
||||||
|
{
|
||||||
|
mult=frameMult;
|
||||||
|
return ChangeState(state,sStateName);
|
||||||
|
}
|
||||||
// Change an animation state token to a new state
|
// Change an animation state token to a new state
|
||||||
inline bool ChangeState(AnimationState& state, const StatesEnum& sStateName) const
|
inline bool ChangeState(AnimationState& state, const StatesEnum& sStateName) const
|
||||||
{
|
{
|
||||||
@ -188,7 +194,7 @@ namespace olc::utils::Animate2D
|
|||||||
// Update an animation state token
|
// Update an animation state token
|
||||||
inline void UpdateState(AnimationState& state, const float fElapsedTime) const
|
inline void UpdateState(AnimationState& state, const float fElapsedTime) const
|
||||||
{
|
{
|
||||||
state.fTime = std::fmod(state.fTime+fElapsedTime,1000);
|
state.fTime = std::fmod(state.fTime+fElapsedTime*mult,1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -148,6 +148,38 @@ std::u32string util::WrapText(PixelGameEngine*pge,std::u32string str,int width,F
|
|||||||
return newStr;
|
return newStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma region std::string util::GetHash(std::string fileName) //DO NOT MODIFY!
|
||||||
|
std::string util::GetHash(std::string fileName){
|
||||||
|
//WARNING! This function is used to save/load files! This means if we ever modify this function all previous save files
|
||||||
|
//will no longer work! IN OTHER WORDS: DO NOT MODIFY THIS FUNCTION!
|
||||||
|
std::ifstream file(fileName);
|
||||||
|
std::string hash="";
|
||||||
|
uint8_t hashIndex=0;
|
||||||
|
while(file.good()){
|
||||||
|
uint8_t hashChar=0;
|
||||||
|
if(hash.size()==std::numeric_limits<uint8_t>::max()){
|
||||||
|
hashChar=hash[hashIndex];
|
||||||
|
}
|
||||||
|
char newChar=file.get();
|
||||||
|
if(newChar=='\r'||newChar=='\f'||newChar=='\n')continue;
|
||||||
|
hashChar+=newChar*21-7;
|
||||||
|
hashChar^=hashIndex;
|
||||||
|
if(hashIndex>0)hashChar+=hash[hashIndex-1];
|
||||||
|
hashChar%=94;
|
||||||
|
hashChar+=32;
|
||||||
|
if(hashChar=='"'||hashChar==',')hashChar+=60;
|
||||||
|
if(hashChar=='|')hashChar++; //FORBIDDEN CHARACTER IN EMSCRIPTEN BUILD!
|
||||||
|
if(hash.size()<std::numeric_limits<uint8_t>::max()){
|
||||||
|
hash+=hashChar;
|
||||||
|
}else{
|
||||||
|
hash[hashIndex]=hashChar;
|
||||||
|
}
|
||||||
|
hashIndex++;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
long double operator""_Pixels(long double unitDist){
|
long double operator""_Pixels(long double unitDist){
|
||||||
return unitDist/100*24.;
|
return unitDist/100*24.;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ namespace olc::util{
|
|||||||
std::string WrapText(PixelGameEngine*pge,std::string str,int width,bool proportional,vd2d scale);
|
std::string WrapText(PixelGameEngine*pge,std::string str,int width,bool proportional,vd2d scale);
|
||||||
std::u32string WrapText(PixelGameEngine*pge,std::u32string str,int width,Font&font,vd2d scale);
|
std::u32string WrapText(PixelGameEngine*pge,std::u32string str,int width,Font&font,vd2d scale);
|
||||||
float angle_difference(float angle_1, float angle_2);
|
float angle_difference(float angle_1, float angle_2);
|
||||||
|
std::string GetHash(std::string file);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TL, class TR>
|
template<class TL, class TR>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
rm -R release
|
rm -R release
|
||||||
mkdir release
|
mkdir release
|
||||||
mkdir release/assets
|
mkdir release/assets
|
||||||
|
mkdir "release/Adventures in Lestoria"
|
||||||
cp -R "Adventures in Lestoria/assets/Campaigns" release/assets
|
cp -R "Adventures in Lestoria/assets/Campaigns" release/assets
|
||||||
cp -R "Adventures in Lestoria/assets/config" release/assets
|
cp -R "Adventures in Lestoria/assets/config" release/assets
|
||||||
cp -R "Adventures in Lestoria/assets/maps" release/assets
|
cp -R "Adventures in Lestoria/assets/maps" release/assets
|
||||||
@ -13,10 +14,10 @@ cp -R "Adventures in Lestoria/assets/npcs" release/assets
|
|||||||
cp -R "Adventures in Lestoria/assets/sounds" release/assets
|
cp -R "Adventures in Lestoria/assets/sounds" release/assets
|
||||||
cp -R "Adventures in Lestoria/assets/themes" release/assets
|
cp -R "Adventures in Lestoria/assets/themes" release/assets
|
||||||
cp -R "Adventures in Lestoria/assets/gamepack.pak" release/assets
|
cp -R "Adventures in Lestoria/assets/gamepack.pak" release/assets
|
||||||
cp -R "Adventures in Lestoria/assets/*.ttf" release/assets
|
cp -R "Adventures in Lestoria/assets/"*.ttf release/assets
|
||||||
cp -R "Adventures in Lestoria/controller_config" release
|
cp -R "Adventures in Lestoria/controller_config" release
|
||||||
mkdir "release/Adventures in Lestoria"
|
cp "Adventures in Lestoria/Adventures in Lestoria/"*.so "release/Adventures in Lestoria"
|
||||||
cp "Adventures in Lestoria/Adventures in Lestoria/*.so" "release/Adventures in Lestoria"
|
cp -R bin release
|
||||||
|
|
||||||
rm release/*.pdb
|
rm release/*.pdb
|
||||||
|
|
||||||
|
2
read_debug_log.ps1
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
clear
|
||||||
|
Get-Content "Adventures in Lestoria/debug.log" -Wait
|