Quapsel 11 months ago
commit 096acb2081
  1. 19
      .gitignore
  2. 8
      Adventures in Lestoria.sln
  3. 4
      Adventures in Lestoria/Ability.cpp
  4. 2
      Adventures in Lestoria/Ability.h
  5. 77
      Adventures in Lestoria/Adventures in Lestoria.rc
  6. 17
      Adventures in Lestoria/Adventures in Lestoria.tiled-project
  7. 92
      Adventures in Lestoria/Adventures in Lestoria.vcxproj
  8. 67
      Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
  9. 269
      Adventures in Lestoria/AdventuresInLestoria.cpp
  10. 13
      Adventures in Lestoria/AdventuresInLestoria.h
  11. 4
      Adventures in Lestoria/Animation.cpp
  12. 2
      Adventures in Lestoria/Animation.h
  13. 4
      Adventures in Lestoria/Arrow.cpp
  14. 2
      Adventures in Lestoria/Attributable.h
  15. 6
      Adventures in Lestoria/AttributableStat.cpp
  16. 21
      Adventures in Lestoria/AttributableStat.h
  17. 247
      Adventures in Lestoria/Audio.cpp
  18. 112
      Adventures in Lestoria/Audio.h
  19. 2
      Adventures in Lestoria/BitwiseEnum.h
  20. 6
      Adventures in Lestoria/BlacksmithCraftingWindow.cpp
  21. 8
      Adventures in Lestoria/Buff.h
  22. 4
      Adventures in Lestoria/Bullet.cpp
  23. 4
      Adventures in Lestoria/Bullet.h
  24. 2
      Adventures in Lestoria/BulletTypes.h
  25. 2
      Adventures in Lestoria/BuyItemWindow.cpp
  26. BIN
      Adventures in Lestoria/C++ Header File (OLC-3).zip
  27. BIN
      Adventures in Lestoria/C++ Source File (OLC-3).zip
  28. 0
      Adventures in Lestoria/C++/scripts/build.sh
  29. 0
      Adventures in Lestoria/C++/scripts/commit.sh
  30. 0
      Adventures in Lestoria/C++/scripts/debug.sh
  31. 0
      Adventures in Lestoria/C++/scripts/filelist
  32. 0
      Adventures in Lestoria/C++/scripts/lines.sh
  33. 2
      Adventures in Lestoria/C++/scripts/md5
  34. 0
      Adventures in Lestoria/C++/scripts/release.sh
  35. 0
      Adventures in Lestoria/C++/scripts/temp
  36. 6
      Adventures in Lestoria/C++/scripts/web.sh
  37. 0
      Adventures in Lestoria/CREDITS
  38. 6
      Adventures in Lestoria/CharacterAbilityPreviewComponent.h
  39. 4
      Adventures in Lestoria/CharacterInfoWindow.cpp
  40. 88
      Adventures in Lestoria/CharacterMenuWindow.cpp
  41. 6
      Adventures in Lestoria/CharacterRotatingDisplay.h
  42. 4
      Adventures in Lestoria/ChargedArrow.cpp
  43. 2
      Adventures in Lestoria/Class.h
  44. 4
      Adventures in Lestoria/ClassDiagram2.cd
  45. 0
      Adventures in Lestoria/ClassDiagram2.png
  46. 2
      Adventures in Lestoria/ClassInfo.h
  47. 4
      Adventures in Lestoria/ClassSelectionWindow.cpp
  48. 2
      Adventures in Lestoria/ConnectionPoint.cpp
  49. 3
      Adventures in Lestoria/ConnectionPoint.h
  50. 2
      Adventures in Lestoria/ConsumableCraftItemWindow.cpp
  51. 6
      Adventures in Lestoria/ConsumableCraftingWindow.cpp
  52. 2
      Adventures in Lestoria/CraftItemWindow.cpp
  53. 2
      Adventures in Lestoria/CraftingRequirement.cpp
  54. 2
      Adventures in Lestoria/CraftingRequirement.h
  55. 0
      Adventures in Lestoria/Crawler_Slime_King_Encounter.txt
  56. 0
      Adventures in Lestoria/Crawler_System_Overview.txt
  57. 4
      Adventures in Lestoria/DEFINES.h
  58. 2
      Adventures in Lestoria/DamageNumber.cpp
  59. 2
      Adventures in Lestoria/DamageNumber.h
  60. 4
      Adventures in Lestoria/Effect.cpp
  61. 4
      Adventures in Lestoria/Effect.h
  62. 2
      Adventures in Lestoria/Emitter.cpp
  63. 4
      Adventures in Lestoria/Emitter.h
  64. 4
      Adventures in Lestoria/EncountersSpawnListScrollableWindowComponent.h
  65. 4
      Adventures in Lestoria/EnergyBolt.cpp
  66. 2
      Adventures in Lestoria/EnhancementStatsLabel.h
  67. 11
      Adventures in Lestoria/EquipSlotButton.h
  68. 2
      Adventures in Lestoria/Error.h
  69. 2
      Adventures in Lestoria/FallingDebris.h
  70. 4
      Adventures in Lestoria/FireBolt.cpp
  71. 2
      Adventures in Lestoria/FunctionPriming.h
  72. 4
      Adventures in Lestoria/GameState.cpp
  73. 10
      Adventures in Lestoria/GameState.h
  74. 0
      Adventures in Lestoria/InitialConcept.txt
  75. 4
      Adventures in Lestoria/InventoryConsumableWindow.cpp
  76. 2
      Adventures in Lestoria/InventoryCreator.cpp
  77. 2
      Adventures in Lestoria/InventoryCreator.h
  78. 6
      Adventures in Lestoria/InventoryScrollableWindowComponent.h
  79. 6
      Adventures in Lestoria/InventoryWindow.cpp
  80. 148
      Adventures in Lestoria/Item.cpp
  81. 36
      Adventures in Lestoria/Item.h
  82. 4
      Adventures in Lestoria/ItemDrop.cpp
  83. 6
      Adventures in Lestoria/ItemDrop.h
  84. 4
      Adventures in Lestoria/ItemLoadoutWindow.cpp
  85. 2
      Adventures in Lestoria/ItemMenuLabel.h
  86. 4
      Adventures in Lestoria/Key.cpp
  87. 2
      Adventures in Lestoria/Key.h
  88. 0
      Adventures in Lestoria/LICENSE
  89. 0
      Adventures in Lestoria/LICENSE_FT.txt
  90. 0
      Adventures in Lestoria/LICENSE_OLC-3.txt
  91. 4
      Adventures in Lestoria/LevelCompleteWindow.cpp
  92. 6
      Adventures in Lestoria/LightningBolt.cpp
  93. 8
      Adventures in Lestoria/LightningBoltEmitter.cpp
  94. 103
      Adventures in Lestoria/LoadFileButton.h
  95. 18
      Adventures in Lestoria/LoadGameWindow.cpp
  96. 84
      Adventures in Lestoria/MainMenuWindow.cpp
  97. 4
      Adventures in Lestoria/Map.cpp
  98. 2
      Adventures in Lestoria/Map.h
  99. 60
      Adventures in Lestoria/Menu.cpp
  100. 47
      Adventures in Lestoria/Menu.h
  101. Some files were not shown because too many files have changed in this diff Show More

19
.gitignore vendored

@ -27,7 +27,8 @@ memoryleak.txt
[Dd]ebug/
[Dd]ebugPublic/
*.tlog/
Crawler/x64/
Adventures in Lestoria/x64/
Adventures in Lestoria/assets/saves/*
[Rr]eleases/
x86/
[Ww][Ii][Nn]32/
@ -368,11 +369,17 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
Crawler/Crawler.html
Crawler/Crawler.data
Crawler/Crawler.js
Crawler/Crawler.wasm
Crawler/pixelGameEngine_wasm.o
Adventures in Lestoria/Adventures in Lestoria
*.tiled-session
/Crawler/Crawler.tiled-session
/Crawler/assets/discordAPI.txt
/CMakeFiles
/CMakeCache.txt
/cmake_install.cmake
/Makefile
Crawler/out
/Adventures in Lestoria/.vscode
/Adventures in Lestoria/.vscode/settings.json
/Adventures in Lestoria/x64
/Adventures in Lestoria/saves
/Adventures in Lestoria/assets/tmpsaves

@ -3,12 +3,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Crawler", "Crawler\Crawler.vcxproj", "{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Adventures in Lestoria", "Adventures in Lestoria\Adventures in Lestoria.vcxproj", "{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Emscripten|x64 = Emscripten|x64
Emscripten|x86 = Emscripten|x86
Release Desktop|x64 = Release Desktop|x64
Release Desktop|x86 = Release Desktop|x86
Release|x64 = Release|x64
@ -19,6 +21,10 @@ Global
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x64.Build.0 = Debug|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x86.ActiveCfg = Debug|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x86.Build.0 = Debug|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x64.ActiveCfg = Emscripten|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x64.Build.0 = Emscripten|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x86.ActiveCfg = Emscripten|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x86.Build.0 = Emscripten|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release Desktop|x64.ActiveCfg = Release Desktop|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release Desktop|x64.Build.0 = Release Desktop|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release Desktop|x86.ActiveCfg = Release Desktop|Win32

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -36,7 +36,7 @@ All rights reserved.
*/
#pragma endregion
#include "Ability.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
INCLUDE_game

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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,44 +1,52 @@
// Microsoft Visual C++ generated resource script.
//
// ... other stuff
#include "resource.h"
#include "Version.h"
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILE_VERSION
PRODUCTVERSION VER_PRODUCT_VERSION
FILEFLAGSMASK 0x17L
FILEVERSION 0,2,1,5299
PRODUCTVERSION 0,2,1,5299
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040704b0"
BEGIN
VALUE "CompanyName", "Sig"
VALUE "FileDescription", "Crawler Game"
VALUE "FileVersion", VER_FILE_VERSION_STR "\0"
VALUE "InternalName", "Crawler.exe"
VALUE "LegalCopyright", "Copyright 2023"
VALUE "OriginalFilename", "Crawler.exe"
VALUE "ProductName", "Crawler"
VALUE "ProductVersion", VER_PRODUCT_VERSION_STR "\0"
END
END
BLOCK "VarFileInfo"
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
VALUE "Translation", 0x407, 1200
END
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Sig Productions"
VALUE "FileDescription", "Adventures in Lestoria"
VALUE "FileVersion", "0.2.1.5299"
VALUE "InternalName", "Crawler.exe"
VALUE "LegalCopyright", "Copyright © 2023-2024"
VALUE "OriginalFilename", "Adventures in Lestoria.exe"
VALUE "ProductName", "Adventures in Lestoria"
VALUE "ProductVersion", "0.2.1.5299"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
@ -49,8 +57,6 @@ END
MAINICON ICON "assets\\heart.ico"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
@ -75,6 +81,15 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// PNG
//
IDB_PNG1 PNG "assets\\AiL_512.png"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////

@ -8,6 +8,17 @@
"."
],
"propertyTypes": [
{
"id": 27,
"name": "BGM",
"storageType": "string",
"type": "enum",
"values": [
"None",
"foresty_1_1"
],
"valuesAsFlags": false
},
{
"color": "#ff290aa4",
"drawFill": true,
@ -160,6 +171,12 @@
"drawFill": true,
"id": 19,
"members": [
{
"name": "Background Music",
"propertyType": "BGM",
"type": "string",
"value": "None"
},
{
"name": "Level Type",
"propertyType": "LevelType",

@ -38,8 +38,9 @@
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{8e3067af-cfe7-4b11-bc6b-b867c32753d7}</ProjectGuid>
<RootNamespace>Crawler</RootNamespace>
<RootNamespace>Adventures in Lestoria</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Adventures in Lestoria</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -131,13 +132,13 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\sigon\source\repos\Crawler\Crawler;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>discord_game_sdk.dll.lib;freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);</AdditionalDependencies>
</Link>
<PreBuildEvent>
@ -154,7 +155,7 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -177,7 +178,7 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;C:\Users\sigon\source\repos\Crawler\Crawler\discord-files</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -197,13 +198,13 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\sigon\source\repos\Crawler\Crawler;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>discord_game_sdk.dll.lib;freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);</AdditionalDependencies>
</Link>
<PreBuildEvent>
@ -224,7 +225,7 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -250,7 +251,7 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;C:\Users\sigon\source\repos\Crawler\Crawler\discord-files</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -274,8 +275,14 @@
</Link>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;</AdditionalIncludeDirectories>
</ClCompile>
<PostBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File ../emscripten_build.ps1</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -File emscripten_build.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten|x64'">
<Link>
@ -284,10 +291,17 @@
</Link>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;</AdditionalIncludeDirectories>
</ClCompile>
<PostBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File ../emscripten_build.ps1</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -File emscripten_build.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\Downloads\olcPixelGameEngine (1).h" />
<ClInclude Include="Ability.h" />
<ClInclude Include="Animation.h" />
<ClInclude Include="Attributable.h" />
@ -295,6 +309,10 @@
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="Audio.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="BitwiseEnum.h">
<SubType>
</SubType>
@ -309,7 +327,7 @@
<ClInclude Include="config.h" />
<ClInclude Include="ConnectionPoint.h" />
<ClInclude Include="CraftingRequirement.h" />
<ClInclude Include="Crawler.h" />
<ClInclude Include="AdventuresInLestoria.h" />
<ClInclude Include="DamageNumber.h" />
<ClInclude Include="DEFINES.h" />
<ClInclude Include="discord-files\achievement_manager.h" />
@ -355,6 +373,11 @@
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="LoadFileButton.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="olcPGEX_SplashScreen.h" />
<ClInclude Include="PlayerMoneyLabel.h">
<SubType>
</SubType>
@ -424,6 +447,10 @@
</SubType>
</ClInclude>
<ClInclude Include="safemap.h" />
<ClInclude Include="SaveFile.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="ScrollableWindowComponent.h" />
<ClInclude Include="InventoryScrollableWindowComponent.h" />
<ClInclude Include="SpawnEncounterLabel.h" />
@ -440,6 +467,14 @@
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="TextEntryLabel.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="TitleScreen.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="VisualNovel.h" />
<ClInclude Include="Test.h" />
<ClInclude Include="Theme.h" />
@ -458,6 +493,10 @@
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="Audio.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="BlacksmithCraftingWindow.cpp">
<SubType>
</SubType>
@ -488,7 +527,7 @@
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="Crawler.cpp" />
<ClCompile Include="AdventuresInLestoria.cpp" />
<ClCompile Include="DamageNumber.cpp" />
<ClCompile Include="discord-files\achievement_manager.cpp" />
<ClCompile Include="discord-files\activity_manager.cpp" />
@ -527,6 +566,10 @@
<ClCompile Include="LevelCompleteWindow.cpp" />
<ClCompile Include="LightningBolt.cpp" />
<ClCompile Include="LightningBoltEmitter.cpp" />
<ClCompile Include="LoadGameWindow.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="MainMenuWindow.cpp" />
<ClCompile Include="Map.cpp" />
<ClCompile Include="Menu.cpp" />
@ -556,6 +599,14 @@
<ClCompile Include="PulsatingFire.cpp" />
<ClCompile Include="Ranger.cpp" />
<ClCompile Include="RUN_STRATEGY.cpp" />
<ClCompile Include="SaveFile.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="SaveFileWindow.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="SellItemWindow.cpp">
<SubType>
</SubType>
@ -572,9 +623,14 @@
<ClCompile Include="State_Story.cpp" />
<ClCompile Include="Test.cpp" />
<ClCompile Include="Thief.cpp" />
<ClCompile Include="TitleScreen.cpp" />
<ClCompile Include="Trapper.cpp" />
<ClCompile Include="Turret.cpp" />
<ClCompile Include="Unlock.cpp" />
<ClCompile Include="UserIDMenu.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="VisualNovel.cpp" />
<ClCompile Include="Warrior.cpp" />
<ClCompile Include="util.cpp" />
@ -586,6 +642,8 @@
<None Include="cpp.hint" />
</ItemGroup>
<ItemGroup>
<Text Include="assets\config\bgm\bgm.txt" />
<Text Include="assets\config\bgm\events.txt" />
<Text Include="assets\config\classes\Ranger.txt" />
<Text Include="assets\config\classes\Thief.txt" />
<Text Include="assets\config\classes\Trapper.txt" />
@ -595,6 +653,7 @@
<Text Include="assets\config\configuration.txt" />
<Text Include="assets\config\gfx\gfx.txt" />
<Text Include="assets\config\gfx\themes.txt" />
<Text Include="assets\config\items\Accessories.txt" />
<Text Include="assets\config\items\Equipment.txt" />
<Text Include="assets\config\items\ItemCategory.txt" />
<Text Include="assets\config\items\ItemDatabase.txt" />
@ -614,8 +673,8 @@
<Text Include="assets\config\shops\Chapter 5 Merchants.txt" />
<Text Include="assets\config\shops\Chapter 6 Merchants.txt" />
<Text Include="assets\config\story\Chapter 1.txt" />
<Text Include="Crawler_Story_Chapter_1 (2).txt" />
<Text Include="Crawler_System_Overview.txt" />
<Text Include="Adventures in Lestoria_Story_Chapter_1 (2).txt" />
<Text Include="Adventures in Lestoria_System_Overview.txt" />
<Text Include="Merchant%27s Items.txt" />
<Text Include="NewClasses.txt" />
<Text Include="InitialConcept.txt" />
@ -624,11 +683,12 @@
<Text Include="TODO.txt" />
</ItemGroup>
<ItemGroup>
<Image Include="assets\AiL_512.png" />
<Image Include="assets\heart.ico" />
<Image Include="assets\menus\Character_Info.png" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Crawler.rc" />
<ResourceCompile Include="Adventures in Lestoria.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

@ -108,7 +108,7 @@
<ClInclude Include="Animation.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Crawler.h">
<ClInclude Include="AdventuresInLestoria.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Player.h">
@ -390,6 +390,27 @@
<ClInclude Include="ItemMenuLabel.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
<ClInclude Include="TextEntryLabel.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
<ClInclude Include="SaveFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LoadFileButton.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
<ClInclude Include="olcPGEX_SplashScreen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\Downloads\olcPixelGameEngine (1).h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TitleScreen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Audio.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Player.cpp">
@ -401,7 +422,7 @@
<ClCompile Include="Monster.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Crawler.cpp">
<ClCompile Include="AdventuresInLestoria.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DamageNumber.cpp">
@ -551,9 +572,6 @@
<ClCompile Include="Test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MainMenuWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LevelCompleteWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
@ -653,6 +671,27 @@
<ClCompile Include="ConsumableCraftItemWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="MainMenuWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="SaveFileWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="SaveFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LoadGameWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="UserIDMenu.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="TitleScreen.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Audio.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
@ -719,15 +758,9 @@
<Text Include="assets\config\items\items.txt">
<Filter>Configurations\Items</Filter>
</Text>
<Text Include="Crawler_System_Overview.txt">
<Filter>Documentation</Filter>
</Text>
<Text Include="assets\config\story\Chapter 1.txt">
<Filter>Configurations\Story</Filter>
</Text>
<Text Include="Crawler_Story_Chapter_1 (2).txt">
<Filter>Documentation\Story</Filter>
</Text>
<Text Include="assets\config\items\Equipment.txt">
<Filter>Configurations\Items</Filter>
</Text>
@ -767,6 +800,13 @@
<Text Include="Merchant%27s Items.txt">
<Filter>Documentation\Menus</Filter>
</Text>
<Text Include="assets\config\items\Accessories.txt">
<Filter>Configurations\Items</Filter>
</Text>
<Text Include="Adventures in Lestoria_Story_Chapter_1 (2).txt" />
<Text Include="Adventures in Lestoria_System_Overview.txt" />
<Text Include="assets\config\bgm\bgm.txt" />
<Text Include="assets\config\bgm\events.txt" />
</ItemGroup>
<ItemGroup>
<Image Include="assets\heart.ico">
@ -775,9 +815,12 @@
<Image Include="assets\menus\Character_Info.png">
<Filter>Documentation\Menus</Filter>
</Image>
<Image Include="assets\AiL_512.png">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Crawler.rc">
<ResourceCompile Include="Adventures in Lestoria.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -36,7 +36,7 @@ All rights reserved.
*/
#pragma endregion
#include "olcPGEX_TransformedView.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "olcUTIL_Camera2D.h"
#include "DamageNumber.h"
#include "Bullet.h"
@ -67,11 +67,14 @@ All rights reserved.
#include "olcPGEX_TTF.h"
#include "MenuItemItemButton.h"
#include "Merchant.h"
#include "SaveFile.h"
#include "TitleScreen.h"
#ifndef __EMSCRIPTEN__
#include "discord.h"
#endif
INCLUDE_EMITTER_LIST
INCLUDE_ITEM_CATEGORIES
bool _DEBUG_MAP_LOAD_INFO = false;
//360x240
@ -84,21 +87,21 @@ std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
safemap<std::string,Renderable>GFX;
safemap<std::string,MapName>LEVEL_NAMES;
utils::datafile DATA;
Crawler*game;
InputGroup Crawler::KEY_LEFT;
InputGroup Crawler::KEY_RIGHT;
InputGroup Crawler::KEY_UP;
InputGroup Crawler::KEY_DOWN;
InputGroup Crawler::KEY_ATTACK;
InputGroup Crawler::KEY_CONFIRM;
InputGroup Crawler::KEY_MENU;
AiL*game;
InputGroup AiL::KEY_LEFT;
InputGroup AiL::KEY_RIGHT;
InputGroup AiL::KEY_UP;
InputGroup AiL::KEY_DOWN;
InputGroup AiL::KEY_ATTACK;
InputGroup AiL::KEY_CONFIRM;
InputGroup AiL::KEY_MENU;
#ifndef __EMSCRIPTEN__
::discord::Core*Discord{};
#endif
float Crawler::SIZE_CHANGE_SPEED=1;
float AiL::SIZE_CHANGE_SPEED=1;
Crawler::Crawler()
AiL::AiL()
{
utils::datafile::Read(DATA,"assets/config/configuration.txt");
@ -134,18 +137,26 @@ Crawler::Crawler()
std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S;
utils::datafile::Read(DATA,ITEM_STATS_CONFIG);
for(auto&[key,value]:DATA.GetProperty("ItemConfiguration").GetKeys()){
std::string config = DATA["ItemConfiguration"][key].GetString();
auto keys=DATA.GetProperty("ItemConfiguration");
for(auto&[key,value]:keys){
std::string config=DATA["ItemConfiguration"][key].GetString();
utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config);
}
DEBUG_PATHFINDING="debug_pathfinding"_I;
for(const std::string&cl:DATA.GetProperty("class_list").GetValues()){
std::vector<std::string>values=DATA.GetProperty("class_list").GetValues();
for(const std::string&cl:values){
std::cout<<cl<<std::endl;
utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt");
}
std::string BGM_CONFIG = CONFIG_PATH + "bgm_config"_S;
utils::datafile::Read(DATA,BGM_CONFIG);
std::string BGM_EVENTS_CONFIG = CONFIG_PATH + "event_config"_S;
utils::datafile::Read(DATA,BGM_EVENTS_CONFIG);
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
sAppName = "GAME_NAME"_S;
@ -153,7 +164,7 @@ Crawler::Crawler()
gameStarted=time(NULL);
}
bool Crawler::OnUserCreate(){
bool AiL::OnUserCreate(){
Font::init();
InitializeDefaultKeybinds();
@ -216,6 +227,7 @@ bool Crawler::OnUserCreate(){
Inventory::AddItem("Wooden Sword");
Inventory::AddItem("Laser Sword");
Inventory::AddItem("Shell Sword");
Inventory::AddItem("Ring of the Slime King",3);
LoadLevel(LEVEL_NAMES["starting_map"_S]);
ChangePlayerClass(WARRIOR);
@ -227,8 +239,12 @@ bool Crawler::OnUserCreate(){
Merchant::Initialize();
TitleScreen::Initialize();
Stats::InitializeDamageReductionTable();
Audio::Initialize();
utils::datafile::INITIAL_SETUP_COMPLETE=true;
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
@ -239,11 +255,12 @@ bool Crawler::OnUserCreate(){
return true;
}
bool Crawler::OnUserUpdate(float fElapsedTime){
bool AiL::OnUserUpdate(float fElapsedTime){
levelTime+=fElapsedTime;
if(!GamePaused()){
GameState::STATE->OnUserUpdate(this);
}
Audio::Update();
RenderWorld(GetElapsedTime());
GameState::STATE->Draw(this);
RenderMenu();
@ -262,32 +279,32 @@ bool Crawler::OnUserUpdate(float fElapsedTime){
return !gameEnd;
}
bool Crawler::LeftHeld(){
bool AiL::LeftHeld(){
return KEY_LEFT.Held();
}
bool Crawler::RightHeld(){
bool AiL::RightHeld(){
return KEY_RIGHT.Held();
}
bool Crawler::UpHeld(){
bool AiL::UpHeld(){
return KEY_UP.Held();
}
bool Crawler::DownHeld(){
bool AiL::DownHeld(){
return KEY_DOWN.Held();
}
bool Crawler::LeftReleased(){
bool AiL::LeftReleased(){
return KEY_LEFT.Released();
}
bool Crawler::RightReleased(){
bool AiL::RightReleased(){
return KEY_RIGHT.Released();
}
bool Crawler::UpReleased(){
bool AiL::UpReleased(){
return KEY_UP.Released();
}
bool Crawler::DownReleased(){
bool AiL::DownReleased(){
return KEY_DOWN.Released();
}
void Crawler::HandleUserInput(float fElapsedTime){
void AiL::HandleUserInput(float fElapsedTime){
if(!Menu::stack.empty())return; //A window being opened means there's no user input allowed.
bool setIdleAnimation=true;
@ -489,7 +506,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
}
}
void Crawler::UpdateCamera(float fElapsedTime){
void AiL::UpdateCamera(float fElapsedTime){
lastWorldShakeAdjust=std::max(0.f,lastWorldShakeAdjust-fElapsedTime);
if(worldShakeTime>0){
worldShakeTime-=fElapsedTime;
@ -507,7 +524,7 @@ void Crawler::UpdateCamera(float fElapsedTime){
view.SetWorldOffset(camera.GetViewPosition());
}
void Crawler::UpdateEffects(float fElapsedTime){
void AiL::UpdateEffects(float fElapsedTime){
for(auto it=EMITTER_LIST.begin();it!=EMITTER_LIST.end();++it){
auto ptr=(*it).get();
ptr->Update(fElapsedTime);
@ -535,7 +552,7 @@ void Crawler::UpdateEffects(float fElapsedTime){
foregroundEffectsToBeInserted.clear();
backgroundEffectsToBeInserted.clear();
}
void Crawler::UpdateBullets(float fElapsedTime){
void AiL::UpdateBullets(float fElapsedTime){
for(auto it=BULLET_LIST.begin();it!=BULLET_LIST.end();++it){
Bullet*b=(*it).get();
b->UpdateFadeTime(fElapsedTime);
@ -602,7 +619,7 @@ void Crawler::UpdateBullets(float fElapsedTime){
}
std::erase_if(BULLET_LIST,[](std::unique_ptr<Bullet>&b){return b->dead;});
}
void Crawler::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float z){
void AiL::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float z){
for(Monster&m:MONSTER_LIST){
if(geom2d::overlaps(geom2d::circle(pos,radius),geom2d::circle(m.GetPos(),12*m.GetSizeMult()))){
m.Hurt(damage,upperLevel,z);
@ -610,7 +627,7 @@ void Crawler::HurtEnemies(vf2d pos,float radius,int damage,bool upperLevel,float
}
}
void Crawler::PopulateRenderLists(){
void AiL::PopulateRenderLists(){
monstersBeforeLower.clear();
monstersAfterLower.clear();
monstersBeforeUpper.clear();
@ -703,7 +720,7 @@ void Crawler::PopulateRenderLists(){
std::sort(monstersAfterLower.begin(),monstersAfterLower.end(),[](Monster*m1,Monster*m2){return m1->GetPos().y<m2->GetPos().y;});
}
void Crawler::RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos){
void AiL::RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos){
if(tileSheet.tileset->animationData.count(tileSheetIndex)){
int animationDuration_ms=int(tileSheet.tileset->animationData[tileSheetIndex].size()*"animation_tile_precision"_I);
int animatedIndex=tileSheet.tileset->animationData[tileSheetIndex][size_t(fmod(levelTime*1000.f,animationDuration_ms)/"animation_tile_precision"_I)];
@ -716,7 +733,7 @@ void Crawler::RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2
}
}
void Crawler::RenderTile(TileRenderData&tileSheet,Pixel col){
void AiL::RenderTile(TileRenderData&tileSheet,Pixel col){
if(tileSheet.tileSheet.tileset->animationData.count(tileSheet.tileID%1000000)){
int animationDuration_ms=int(tileSheet.tileSheet.tileset->animationData[tileSheet.tileID%1000000].size()*"animation_tile_precision"_I);
int animatedIndex=tileSheet.tileSheet.tileset->animationData[tileSheet.tileID%1000000][size_t(fmod(levelTime*1000.f,animationDuration_ms)/"animation_tile_precision"_I)];
@ -729,7 +746,7 @@ void Crawler::RenderTile(TileRenderData&tileSheet,Pixel col){
}
}
void Crawler::RenderWorld(float fElapsedTime){
void AiL::RenderWorld(float fElapsedTime){
LayerTag*bridgeLayer=nullptr;
bool bridgeLayerFade=false;
@ -1232,11 +1249,11 @@ void Crawler::RenderWorld(float fElapsedTime){
}
}
Player*Crawler::GetPlayer(){
Player*AiL::GetPlayer(){
return player.get();
}
void Crawler::RenderHud(){
void AiL::RenderHud(){
ItemOverlay::Draw();
RenderCooldowns();
@ -1288,7 +1305,7 @@ void Crawler::RenderHud(){
DrawShadowStringDecal({0,12},"Button Hold Time: "+std::to_string(Menu::menus[INVENTORY_CONSUMABLES]->buttonHoldTime));
}}
void Crawler::RenderCooldowns(){
void AiL::RenderCooldowns(){
std::vector<Ability>cooldowns{
player->GetAbility1(),
player->GetAbility2(),
@ -1393,12 +1410,12 @@ void Crawler::RenderCooldowns(){
}
}
void Crawler::AddEffect(std::unique_ptr<Effect>foreground,std::unique_ptr<Effect> background){
void AiL::AddEffect(std::unique_ptr<Effect>foreground,std::unique_ptr<Effect> background){
AddEffect(std::move(background),true);
AddEffect(std::move(foreground));
}
void Crawler::AddEffect(std::unique_ptr<Effect> foreground,bool back){
void AiL::AddEffect(std::unique_ptr<Effect> foreground,bool back){
if(back){
backgroundEffectsToBeInserted.push_back(std::move(foreground));
} else {
@ -1406,11 +1423,11 @@ void Crawler::AddEffect(std::unique_ptr<Effect> foreground,bool back){
}
}
vf2d Crawler::GetWorldMousePos(){
vf2d AiL::GetWorldMousePos(){
return GetMousePos()+view.GetWorldOffset();
}
void Crawler::SetupWorldShake(float duration){
void AiL::SetupWorldShake(float duration){
worldShakeVel={13,-13};
worldShakeTime=duration;
worldShake=vf2d{player->GetPos()};
@ -1418,7 +1435,7 @@ void Crawler::SetupWorldShake(float duration){
}
void Crawler::InitializeLevel(std::string mapFile,MapName map){
void AiL::InitializeLevel(std::string mapFile,MapName map){
TMXParser level(mapFile);
size_t slashMarker = mapFile.find_last_of('/');
@ -1532,7 +1549,7 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
}
}
void Crawler::LoadLevel(MapName map){
void AiL::LoadLevel(MapName map){
SPAWNER_LIST.clear();
foregroundTileGroups.clear();
upperForegroundTileGroups.clear();
@ -1769,15 +1786,15 @@ void Crawler::LoadLevel(MapName map){
pathfinder.Initialize();
}
bool Crawler::IsUpperForegroundTile(int tileID){
bool AiL::IsUpperForegroundTile(int tileID){
return tileID>=1000000;
}
bool Crawler::IsForegroundTile(TilesheetData sheet,int tileID){
bool AiL::IsForegroundTile(TilesheetData sheet,int tileID){
return sheet.tileset->foregroundTiles.find(tileID)!=sheet.tileset->foregroundTiles.end();
}
TilesheetData Crawler::GetTileSheet(MapName map,int tileID){
TilesheetData AiL::GetTileSheet(MapName map,int tileID){
std::vector<XMLTag>&tileData=MAP_DATA[map].TilesetData;
if(tileData.size()==1){
size_t slashMarkerSourceDir = tileData[0].data["source"].find_last_of('/');
@ -1797,18 +1814,18 @@ TilesheetData Crawler::GetTileSheet(MapName map,int tileID){
}
}
bool Crawler::HasTileCollision(MapName map,vf2d pos,bool upperLevel){
bool AiL::HasTileCollision(MapName map,vf2d pos,bool upperLevel){
geom2d::rect<int>collisionRect=GetTileCollision(map,pos,upperLevel);
vi2d collisionRectSnapPos=vi2d{pos/float(game->GetCurrentMap().tilewidth)}*game->GetCurrentMap().tilewidth;
collisionRect.pos+=collisionRectSnapPos;
return geom2d::overlaps(collisionRect,pos);
}
bool Crawler::IsBridgeLayer(LayerTag&layer){
bool AiL::IsBridgeLayer(LayerTag&layer){
return layer.tag.data.find("class")!=layer.tag.data.end()&&layer.tag.data["class"]=="Bridge";
}
geom2d::rect<int>Crawler::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
geom2d::rect<int>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
if(pos.x<0||pos.y<0||pos.x>=GetCurrentMap().width*game->GetCurrentMap().tilewidth||pos.y>=GetCurrentMap().height*game->GetCurrentMap().tilewidth)return NO_COLLISION;
#pragma region Lower Bridge Collision Check
if(!upperLevel){ //We are looking for lower bridge collisions.
@ -1852,15 +1869,15 @@ geom2d::rect<int>Crawler::GetTileCollision(MapName map,vf2d pos,bool upperLevel)
return foundRect;
}
MapName Crawler::GetCurrentLevel(){
MapName AiL::GetCurrentLevel(){
return currentLevel;
}
std::map<std::string,std::vector<ZoneData>>&Crawler::GetZoneData(MapName map){
std::map<std::string,std::vector<ZoneData>>&AiL::GetZoneData(MapName map){
return MAP_DATA[map].ZoneData;
}
void Crawler::ChangePlayerClass(Class cl){
void AiL::ChangePlayerClass(Class cl){
Ability itemAbility1=player->useItem1;
Ability itemAbility2=player->useItem2;
Ability itemAbility3=player->useItem3;
@ -1913,7 +1930,7 @@ void Crawler::ChangePlayerClass(Class cl){
Player::moneyListeners=moneyListeners;
}
void Crawler::InitializeClasses(){
void AiL::InitializeClasses(){
Warrior::Initialize();
Thief::Initialize();
Ranger::Initialize();
@ -1928,42 +1945,42 @@ void Crawler::InitializeClasses(){
Witch::InitializeClassAbilities();
}
std::string Crawler::GetString(std::string key){
std::string AiL::GetString(std::string key){
return DATA.GetProperty(key).GetString();
}
datafilestringdata Crawler::GetStringList(std::string key){
datafilestringdata AiL::GetStringList(std::string key){
return {DATA,key};
}
int Crawler::GetInt(std::string key){
int AiL::GetInt(std::string key){
return DATA.GetProperty(key).GetInt();
}
datafileintdata Crawler::GetIntList(std::string key){
datafileintdata AiL::GetIntList(std::string key){
return {DATA,key};
}
float Crawler::GetFloat(std::string key){
float AiL::GetFloat(std::string key){
return float(DATA.GetProperty(key).GetReal());
}
datafilefloatdata Crawler::GetFloatList(std::string key){
datafilefloatdata AiL::GetFloatList(std::string key){
return {DATA,key};
}
double Crawler::GetDouble(std::string key){
double AiL::GetDouble(std::string key){
return DATA.GetProperty(key).GetReal();
}
datafiledoubledata Crawler::GetDoubleList(std::string key){
datafiledoubledata AiL::GetDoubleList(std::string key){
return {DATA,key};
}
int main()
{
{
Crawler demo;
AiL demo;
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4))
demo.Start();
}
@ -1983,7 +2000,7 @@ int main()
while(file.good()){
std::string line;
std::getline(file,line);
if(line.find("Crawler\\")!=std::string::npos){
if(line.find("AiL\\")!=std::string::npos){
if(!leaked){
leaked=true;
std::cout<<std::endl<<std::endl<<std::endl<<"Memory leak detected!"<<std::endl;
@ -2000,47 +2017,47 @@ int main()
}
datafilestringdata operator ""_s(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return {DATA,std::string(key,len)};
}
datafileintdata operator ""_i(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return {DATA,std::string(key,len)};
}
datafilefloatdata operator ""_f(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return {DATA,std::string(key,len)};
}
datafiledoubledata operator ""_d(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return {DATA,std::string(key,len)};
}
Pixel operator ""_Pixel(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return {uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(0)),uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(1)),uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(2)),uint8_t(DATA.GetProperty(std::string(key,len)).GetInt(3))};
}
std::string operator ""_S(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return DATA.GetProperty(std::string(key,len)).GetString();
}
int operator ""_I(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return DATA.GetProperty(std::string(key,len)).GetInt();
}
float operator ""_F(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return float(DATA.GetProperty(std::string(key,len)).GetReal());
}
float operator ""_FRange(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return float(util::random(float(DATA.GetProperty(std::string(key,len)).GetReal(1)-DATA.GetProperty(std::string(key,len)).GetReal(0)))+DATA.GetProperty(std::string(key,len)).GetReal(0));
}
float operator ""_Pct(long double pct){
@ -2048,16 +2065,16 @@ float operator ""_Pct(long double pct){
}
double operator ""_D(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return DATA.GetProperty(std::string(key,len)).GetReal();
}
datafile operator ""_A(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
AiL::OutputDebugInfo(key,len);
return DATA.GetProperty(std::string(key,len));
}
void Crawler::OutputDebugInfo(const char*key,std::size_t len){
void AiL::OutputDebugInfo(const char*key,std::size_t len){
if(utils::datafile::DEBUG_ACCESS_OPTIONS){
std::string k=std::string(key);
if(!k.starts_with("debug_")){
@ -2066,11 +2083,14 @@ void Crawler::OutputDebugInfo(const char*key,std::size_t len){
}
}
bool Crawler::IsReflectiveTile(TilesheetData tileSheet,int tileID){
bool AiL::IsReflectiveTile(TilesheetData tileSheet,int tileID){
return tileSheet.tileset->reflectiveData.find(tileID)!=tileSheet.tileset->reflectiveData.end();
}
bool Crawler::OnUserDestroy(){
bool AiL::OnUserDestroy(){
if(GameState::STATE!=GameState::states[States::MAIN_MENU]){ //If we're on the main menu, we don't have a save file loaded. So we would skip saving the game.
SaveFile::SaveGame();
}
GFX.Reset();
for(auto&[key,value]:MAP_DATA){
if(MAP_DATA[key].optimizedTile!=nullptr){
@ -2091,7 +2111,7 @@ bool Crawler::OnUserDestroy(){
return true;
}
void Crawler::InitializeLevels(){
void AiL::InitializeLevels(){
#define INITLEVEL(map) \
LEVEL_NAMES[#map]=map; \
InitializeLevel("map_path"_S + "Levels."#map ## _S,map);
@ -2109,22 +2129,22 @@ void Crawler::InitializeLevels(){
LEVEL_NAMES.SetInitialized();
}
void Crawler::SpawnMonster(vf2d pos,MonsterData&data,bool upperLevel,bool isBossSpawn){
void AiL::SpawnMonster(vf2d pos,MonsterData&data,bool upperLevel,bool isBossSpawn){
monstersToBeSpawned.push_back(Monster(pos,data,upperLevel,isBossSpawn));
if(isBossSpawn){
totalBossEncounterMobs++;
}
}
void Crawler::DrawPie(vf2d center,float radius,float degreesCut,Pixel col){
void AiL::DrawPie(vf2d center,float radius,float degreesCut,Pixel col){
DrawPolygonDecal(nullptr,circleCooldownPoints,circleCooldownPoints,std::max(1,int(degreesCut/4)),center,radius,col);
}
void Crawler::DrawSquarePie(vf2d center,float radius,float degreesCut,Pixel col){
void AiL::DrawSquarePie(vf2d center,float radius,float degreesCut,Pixel col){
DrawPolygonDecal(nullptr,squareCircleCooldownPoints,squareCircleCooldownPoints,std::max(1,int(degreesCut/4)),center,radius,col);
}
void Crawler::InitializeDefaultKeybinds(){
void AiL::InitializeDefaultKeybinds(){
Player::KEY_ABILITY1.AddKeybind({KEY,Q});
Player::KEY_ABILITY2.AddKeybind({KEY,E});
Player::KEY_ABILITY3.AddKeybind({KEY,R});
@ -2147,16 +2167,16 @@ void Crawler::InitializeDefaultKeybinds(){
KEY_MENU.AddKeybind({KEY,ESCAPE});
}
void Crawler::SetBossNameDisplay(std::string name,float time){
void AiL::SetBossNameDisplay(std::string name,float time){
bossName=name;
bossDisplayTimer=time;
}
bool Crawler::InBossEncounter(){
bool AiL::InBossEncounter(){
return bossName!="";
}
void Crawler::StartBossEncounter(){
void AiL::StartBossEncounter(){
if(!encounterStarted){
encounterStarted=true;
totalDamageDealt=0;
@ -2164,7 +2184,7 @@ void Crawler::StartBossEncounter(){
}
}
void Crawler::DisplayBossEncounterInfo(){
void AiL::DisplayBossEncounterInfo(){
if(bossDisplayTimer>0){
std::string displayText="- "+bossName+" -";
@ -2196,18 +2216,18 @@ void Crawler::DisplayBossEncounterInfo(){
}
void Crawler::BossDamageDealt(int damage){
void AiL::BossDamageDealt(int damage){
totalDamageDealt+=damage;
}
void Crawler::ReduceBossEncounterMobCount(){
void AiL::ReduceBossEncounterMobCount(){
totalBossEncounterMobs--;
if(totalBossEncounterMobs<0){
ERR("WARNING! Boss Encounter mob count is less than zero, THIS SHOULD NOT BE HAPPENING!");
}
}
void Crawler::RenderMenu(){
void AiL::RenderMenu(){
if(!GamePaused()&&Menu::stack.size()>0){
Menu::stack.back()->Update(this);
}
@ -2219,7 +2239,7 @@ void Crawler::RenderMenu(){
}
}
void Crawler::InitializeGraphics(){
void AiL::InitializeGraphics(){
circleCooldownPoints.push_back({0,0});
squareCircleCooldownPoints.push_back({0,0});
for(int i=0;i<=360;i+=4){
@ -2307,11 +2327,11 @@ void Crawler::InitializeGraphics(){
std::cout<<GFX.size()<<" images have been loaded."<<std::endl;
}
MapTag Crawler::GetCurrentMap(){
MapTag AiL::GetCurrentMap(){
return MAP_DATA[GetCurrentLevel()].MapData;
}
void Crawler::ValidateGameStatus(){
void AiL::ValidateGameStatus(){
if(IToggleable::uninitializedToggleGroupItems.size()>0){
for(IToggleable*item:IToggleable::uninitializedToggleGroupItems){
std::cout<<"\tUninitialized Toggle Item Ptr: 0x"<<std::hex<<item<<std::endl;
@ -2329,28 +2349,28 @@ void Crawler::ValidateGameStatus(){
}
}
void Crawler::RenderVersionInfo(){
void AiL::RenderVersionInfo(){
std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD));
DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4f,versionStr,WHITE,BLACK,{0.4f,0.4f},std::numeric_limits<float>::max(),0.4f);
}
int Crawler::GetCurrentChapter(){
int AiL::GetCurrentChapter(){
return chapter;
}
void Crawler::SetChapter(int chapter){
void AiL::SetChapter(int chapter){
this->chapter=chapter;
for(MenuComponent*component:Menu::chapterListeners){
component->OnChapterUpdate(chapter);
}
}
const std::weak_ptr<Item>Crawler::GetLoadoutItem(int slot){
const std::weak_ptr<Item>AiL::GetLoadoutItem(int slot){
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
return loadout[slot];
}
void Crawler::SetLoadoutItem(int slot,std::string itemName){
void AiL::SetLoadoutItem(int slot,std::string itemName){
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
if(Inventory::GetItemCount(itemName)>0){
loadout[slot]=Inventory::CopyItem(itemName)[0];
@ -2399,7 +2419,7 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
}
}
bool Crawler::UseLoadoutItem(int slot){
bool AiL::UseLoadoutItem(int slot){
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
if(GetLoadoutItem(slot).lock()->Amt()>0){
Inventory::UseItem(GetLoadoutItem(slot).lock()->ActualName());
@ -2409,7 +2429,7 @@ bool Crawler::UseLoadoutItem(int slot){
return false;
}
void Crawler::ClearLoadoutItem(int slot){
void AiL::ClearLoadoutItem(int slot){
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
loadout[slot].reset();
InputGroup*inputGroup=nullptr;
@ -2452,7 +2472,7 @@ void Crawler::ClearLoadoutItem(int slot){
}
}
void Crawler::RenderFadeout(){
void AiL::RenderFadeout(){
uint8_t alpha=0;
if(fadeOutDuration>0){
fadeOutDuration=std::max(0.f,fadeOutDuration-GetElapsedTime());
@ -2468,16 +2488,16 @@ void Crawler::RenderFadeout(){
FillRectDecal({0,0},GetScreenSize(),{0,0,0,alpha});
}
bool Crawler::GamePaused(){
bool AiL::GamePaused(){
return fadeOutDuration>0;
}
void Crawler::EndGame(){
void AiL::EndGame(){
gameEnd=true;
}
#ifndef __EMSCRIPTEN__
::discord::Result Crawler::SetupDiscord(){
::discord::Result AiL::SetupDiscord(){
auto result=::discord::Core::Create(1186719371750555780,DiscordCreateFlags_NoRequireDiscord,&Discord);
if(result==::discord::Result::Ok){
Discord->SetLogHook(
@ -2493,21 +2513,21 @@ void Crawler::EndGame(){
}
#endif
void Crawler::UpdateDiscordStatus(std::string levelName,std::string className){
void AiL::UpdateDiscordStatus(std::string levelName,std::string className){
#ifndef __EMSCRIPTEN__
if(Discord){
::discord::Activity newActivity{};
newActivity.SetDetails(levelName.c_str());
newActivity.SetState(std::format("Level {} {}",player->Level(),className).c_str());
discord::ActivityTimestamps&timestamps=newActivity.GetTimestamps();
timestamps.SetStart(gameStarted);
newActivity.SetType(discord::ActivityType::Playing);
discord::ActivityAssets&assets=newActivity.GetAssets();
assets.SetLargeImage("heart_512");
assets.SetLargeImage("ail_512");
assets.SetLargeText(game->sAppName.c_str());
assets.SetSmallText(std::format("Level {} {}",player->Level(),className).c_str());
if(levelName!="Main Menu"){
newActivity.SetState(std::format("Level {} {}",player->Level(),className).c_str());
assets.SetSmallText(std::format("Level {} {}",player->Level(),className).c_str());
std::for_each(className.begin(),className.end(),[](char&c){c=std::tolower(c);});
assets.SetSmallImage(("nico-"+className+"_512").c_str());
}
@ -2526,10 +2546,43 @@ void Crawler::UpdateDiscordStatus(std::string levelName,std::string className){
#endif
}
void Crawler::InitializePlayerLevelCap(){
void AiL::InitializePlayerLevelCap(){
while(DATA["PlayerXP"].HasProperty(std::format("LEVEL[{}]",player->levelCap+1))){
player->levelCap++;
}
if(player->levelCap<=1)ERR("Could not detect level cap properly!")
std::cout<<"Level cap detected as "<<int(player->levelCap)<<std::endl;
}
void AiL::ResetGame(){
GameState::ChangeState(States::MAIN_MENU,0.5f);
for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){
Inventory::UnequipItem(EquipSlot(i));
}
for(auto&[cat,items]:ITEM_CATEGORIES){
Inventory::Clear(cat);
}
player->level=1;
player->stats.Reset();
player->ResetAccumulatedXP();
player->totalXPEarned=0;
player->SetMoney(100U);
for(int i=0;i<loadout.size();i++){
game->ClearLoadoutItem(i);
}
Unlock::unlocks.clear();
Unlock::Initialize();
State_OverworldMap::SetStageMarker("Stage I-I");
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
SetChapter(1);
SaveFile::SetSaveFileName("");
}
void AiL::OnRequestCompleted(const std::string_view receivedData)const{
responseCallback(receivedData);
}
std::string operator ""_FS(const char*key,std::size_t len){
AiL::OutputDebugInfo(key,len);
return DATA.GetProperty(std::string(key,len)).GetFullString();
}

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -53,12 +53,15 @@ All rights reserved.
#ifndef __EMSCRIPTEN__
#include "discord.h"
#endif
#include "Audio.h"
class Crawler : public olc::PixelGameEngine
class AiL : public olc::PixelGameEngine
{
friend class GameState;
friend class State_GameRun;
friend class SaveFile;
friend class sig::Animation;
friend class Audio;
std::unique_ptr<Player>player;
public:
Pathfinding pathfinder;
@ -114,13 +117,15 @@ private:
bool gameEnd=false;
std::vector<Monster>monstersToBeSpawned;
time_t gameStarted;
std::function<void(std::string_view)>responseCallback;
void ValidateGameStatus();
#ifndef __EMSCRIPTEN__
::discord::Result SetupDiscord();
#endif
Audio audioEngine;
public:
Crawler();
AiL();
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
bool OnUserDestroy() override;
@ -206,6 +211,8 @@ public:
void EndGame();
void UpdateDiscordStatus(std::string levelName,std::string className);
void InitializePlayerLevelCap();
void ResetGame();
void OnRequestCompleted(const std::string_view receivedData)const override;
struct TileGroupData{
vi2d tilePos;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -36,7 +36,7 @@ All rights reserved.
*/
#pragma endregion
#include "Animation.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "safemap.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "BulletTypes.h"
#include "Effect.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "util.h"
#include "olcUTIL_Geometry2D.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:
@ -174,3 +174,7 @@ const bool ItemAttribute::operator==(const ItemAttribute&rhs)const{
const bool ItemAttribute::ShowAsDecimal()const{
return showDecimal;
}
const std::string_view ItemAttribute::ActualName()const{
return originalName;
}

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:
@ -30,7 +30,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Portions of this software are copyright © 2023 The FreeType
Portions of this software are copyright <EFBFBD> 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
@ -49,7 +49,7 @@ class Player;
class Monster;
class ItemAttribute{
friend class Crawler;
friend class AiL;
std::string name;
std::string originalName;
bool isPct;
@ -62,6 +62,7 @@ public:
ItemAttribute(std::string_view originalName,std::string_view name,bool isPct,bool showDecimal,std::string_view modifies=""sv);
static ItemAttribute&Get(const std::string_view name,const std::optional<std::variant<Player*,Monster*>>target={});
const std::string_view Name()const;
const std::string_view ActualName()const;
const std::string_view Modifies()const;
const bool DisplayAsPercent()const;
const bool ShowAsDecimal()const;
@ -82,7 +83,7 @@ public:
ItemAttributable&operator+=(Stats&rhs);
//Returns a copy of all the attributes to be passed to a new instance easily / to sync values between both.
inline void copyTo(ItemAttributable&target){
inline void copyTo(ItemAttributable&target)const{
target.attributes=attributes;
}
inline float&get(std::string_view a){
@ -95,10 +96,20 @@ public:
return get_readOnly(ItemAttribute::Get(a));
}
inline const float&get_readOnly(const ItemAttribute&a)const{
static float DEFAULT=0;
if(attributes.count(a)){
return attributes.at(a);
}
return 0;
return DEFAULT;
}
inline auto begin()const{
return attributes.begin();
}
inline auto end()const{
return attributes.end();
}
inline void clear(){
attributes.clear();
}
};

@ -0,0 +1,247 @@
#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 © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Audio.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
INCLUDE_game
INCLUDE_DATA
float Audio::defaultFadeTime;
void Audio::Initialize(){
Engine().SetBackgroundPlay(true);
Self().events.insert("Default Volume");
for(auto&[key,data]:DATA["Events"]){
Self().events.insert(key);
}
for(auto&[songFileName,size]:DATA["BGM"]){
auto&data=DATA["BGM"][songFileName];
if(songFileName!="Default Fade Time"){
int channelCounter=0;
BGM&bgm=Self().bgm[songFileName];
bgm.SetFileName(songFileName);
bgm.SetName(data["Track Name"].GetString());
while(data.HasProperty(std::format("channel[{}]",channelCounter))){
std::string channelName=data[std::format("channel[{}]",channelCounter)].GetString();
if(!std::filesystem::exists("bgm_directory"_S+channelName))ERR(std::format("WARNING! Could not load file {} for track {}",channelName,songFileName));
bgm.AddChannel(channelName);
channelCounter++;
}
if(!data.HasProperty("Default Volume"))ERR(std::format("WARNING! Track {} does not have a Default Volume parameter!",bgm.GetName()));
if(data["Default Volume"].GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! Default Volume parameters do not match channel count. {} != {}",data["Default Volume"].GetValueCount(),bgm.GetChannelCount()));
VolumeList volumes;
for(int i=0;i<data["Default Volume"].GetValueCount();i++){
volumes.push_back(data["Default Volume"].GetInt(i)/100.f);
}
bgm.AddEventVolumes("Default Volume",volumes);
if(data.HasProperty("Fade Time")){
bgm.SetFadeTime(data["Fade Time"].GetReal());
}else{
bgm.SetFadeTime(defaultFadeTime);
}
if(data.HasProperty("Events")){
for(auto&[eventName,size]:DATA["Events"]){
auto&eventData=data["Events"][eventName];
if(eventData.GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! {} parameters do not match channel count. {} != {}",eventName,eventData.GetValueCount(),bgm.GetChannelCount()));
VolumeList volumes;
for(int i=0;i<eventData.GetValueCount();i++){
volumes.push_back(eventData.GetInt(i)/100.f);
}
bgm.AddEventVolumes(eventName,volumes);
}
}
}else{
defaultFadeTime=data.GetReal();
}
}
}
MiniAudio&Audio::Engine(){
return game->audioEngine.audioEngine;
}
void Audio::Play(const std::string_view sound){
Engine().Play(std::string(sound));
};
void Audio::PlayBGM(const std::string_view sound,const bool loop){
BGM&track=Self().bgm[std::string(sound)];
StopBGM(); //Stop any currently playing track.
Self().playParams={std::string(sound),loop};
Self().playBGMWaitTime=0.7f;
};
void Audio::StopBGM(){
if(Self().BGMIsPlaying()){
BGM&currentTrack=Self().bgm[Self().currentBGM];
for(int trackID:currentTrack.GetChannelIDs()){
Engine().Stop(trackID);
}
}
}
const bool Audio::BGMIsPlaying(){
return Self().currentBGM.length()>0;
}
const Volume&Audio::BGM::GetVolume(const Event&eventName,const ChannelID&id)const{
return eventVolumes.GetVolumes(eventName).at(id);
}
void Audio::BGM::Load(){
BGM&bgm=Self().bgm[Self().currentBGM];
if(Self().BGMIsPlaying()){
bgm.Unload();
}
Self().currentBGM=songFileName;
BGM&newBgm=Self().bgm[songFileName];
if(newBgm.channels.size()>0)ERR(std::format("WARNING! The size of the channels list is greater than zero! Size: {}",bgm.channels.size()));
for(const ChannelName&channel:newBgm.GetChannels()){
ChannelID soundID=Engine().LoadSound("bgm_directory"_S+channel);
newBgm.channels.push_back(soundID);
}
}
void Audio::BGM::Unload(){
BGM&bgm=Self().bgm[Self().currentBGM];
for(const ChannelID&id:channels){
Engine().UnloadSound(id);
}
channels.clear();
Self().currentBGM="";
}
const ChannelID&Audio::BGM::GetChannelID(const int index){
return channels[index];
}
const ChannelIDList&Audio::BGM::GetChannelIDs()const{
return channels;
}
const std::vector<ChannelName>&Audio::BGM::GetChannels()const{
return channelNames;
}
void Audio::BGM::SetFadeTime(const float fadeTime){
this->fadeTime=fadeTime;
}
void Audio::BGM::AddEventVolumes(const Event&eventName,const VolumeList&volumes){
eventVolumes.AddEventInfo(eventName,volumes);
}
const size_t Audio::BGM::GetChannelCount()const{
return channelNames.size();
}
const SongName&Audio::BGM::GetName()const{
return songName;
}
void Audio::BGM::SetName(std::string_view name){
songName=name;
}
void Audio::BGM::SetFileName(std::string_view name){
songFileName=name;
}
void Audio::BGM::AddChannel(const ChannelName&name){
channelNames.push_back(name);
}
const VolumeList&Audio::EventData::GetVolumes(const Event&event)const{
if(eventInfo.find(event)!=eventInfo.end())return eventInfo.at(event);
return eventInfo.at("Default Volume");
}
void Audio::EventData::AddEventInfo(const Event&eventName,const VolumeList&volumes){
eventInfo[eventName]=volumes;
}
Audio&Audio::Self(){
return game->audioEngine;
}
const Event&Audio::GetAudioEvent(){
return Self().currentAudioEvent;
}
void Audio::SetAudioEvent(const Event&eventName){
if(Self().events.find(eventName)==Self().events.end())ERR(std::format("WARNING! cannot find event {}",eventName));
Self().currentAudioEvent=eventName;
if(Audio::BGMIsPlaying()){
BGM&currentBgm=Self().bgm[Self().currentBGM];
for(int currentTrackIndex=0;int trackID:currentBgm.GetChannelIDs()){
Engine().SetVolume(trackID,currentBgm.GetVolume(eventName,currentTrackIndex));
currentTrackIndex++;
}
}
}
std::string operator""_SFX(const char*key,size_t length){
return "sfx_directory"_S+std::string(key,length);
}
const SongName&Audio::GetTrackName(){
return Self().currentBGM;
}
void Audio::Update(){
if(Self().playBGMWaitTime>0.f){
Self().playBGMWaitTime=std::max(Self().playBGMWaitTime-game->GetElapsedTime(),0.f);
if(Self().playBGMWaitTime==0.f){
BGM&track=Self().bgm[Self().playParams.sound];
track.Load();
for(int channelListIndex=0;int trackID:track.GetChannelIDs()){
Engine().SetVolume(trackID,track.GetVolume(Self().currentAudioEvent,channelListIndex));
Engine().Play(trackID,Self().playParams.loop);
channelListIndex++;
}
}
}
}

@ -0,0 +1,112 @@
#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 © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#pragma once
#include "olcPGEX_MiniAudio.h"
#include "config.h"
#include <set>
using SongName=std::string;
using Event=std::string;
using ChannelName=std::string;
using ChannelID=int;
using ChannelIDList=std::vector<ChannelID>;
using Volume=float;
using VolumeList=std::vector<Volume>;
class Audio{
public:
static Audio&Self();
static MiniAudio&Engine();
static void Initialize();
static void Update();
static void Play(const std::string_view sound);
//Play a BGM given a name found in bgm.txt configuration file.
static void PlayBGM(const std::string_view sound,const bool loop=true);
static void StopBGM();
static const Event&GetAudioEvent();
static const SongName&GetTrackName();
static void SetAudioEvent(const Event&eventName);
static const bool BGMIsPlaying();
private:
struct BGMPlayParams{
std::string sound;
bool loop;
};
class EventData{
public:
void AddEventInfo(const Event&eventName,const VolumeList&volumes);
const VolumeList&GetVolumes(const Event&event)const;
private:
std::map<Event,VolumeList>eventInfo;
};
class BGM{
public:
void Load();
const size_t GetChannelCount()const;
const std::vector<ChannelName>&GetChannels()const;
const SongName&GetName()const;
const Volume&GetVolume(const Event&eventName,const ChannelID&id)const;
void SetName(std::string_view name);
void SetFileName(std::string_view name);
void AddChannel(const ChannelName&name);
void AddEventVolumes(const Event&eventName,const VolumeList&volumes);
void SetFadeTime(const float fadeTime);
const ChannelID&GetChannelID(const int index);
const ChannelIDList&GetChannelIDs()const;
private:
std::string songName; //Name of the track.
std::string songFileName; //Name of the key in bgm.
ChannelIDList channels;
std::vector<ChannelName>channelNames;
EventData eventVolumes;
float fadeTime="BGM.Default Fade Time"_F;
void Unload();
};
private:
MiniAudio audioEngine;
SongName currentBGM="";
std::map<SongName,BGM>bgm;
std::set<Event>events;
static float defaultFadeTime;
Event currentAudioEvent="Default Volume";
float playBGMWaitTime=0.0f;
BGMPlayParams playParams;
};
std::string operator""_SFX(const char*key,size_t length);

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "Menu.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "MenuItemItemButton.h"
#include "PlayerMoneyLabel.h"
#include "RowInventoryScrollableWindowComponent.h"
@ -172,7 +172,7 @@ void Menu::InitializeBlacksmithCraftingWindow(){
auto moneyIcon=blacksmithWindow->ADD("Money Icon",MenuIconButton)({moneyIconPos,{24,24}},GFX["money.png"].Decal(),DO_NOTHING,IconButtonAttr::NOT_SELECTABLE|IconButtonAttr::NO_OUTLINE|IconButtonAttr::NO_BACKGROUND)END;
std::string moneyText=std::to_string(game->GetPlayer()->GetMoney());
vf2d moneyTextSize=game->GetTextSizeProp(moneyText)*2;
auto moneyDisplay=blacksmithWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
auto moneyDisplay=blacksmithWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN|ComponentAttr::FIT_TO_LABEL)END;
moneyDisplay->SetRightAlignment(true);
Player::AddMoneyListener(moneyDisplay);
#pragma endregion

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -48,7 +48,7 @@ enum BuffType{
RESTORATION_DURING_CAST,
};
class Crawler;
class AiL;
struct Buff{
BuffType type;
@ -57,7 +57,7 @@ struct Buff{
float intensity=1;
float nextTick=0;
std::set<ItemAttribute> attr;
std::function<void(Crawler*,int)>repeatAction;
std::function<void(AiL*,int)>repeatAction;
inline Buff(BuffType type,float duration,float intensity)
:type(type),duration(duration),intensity(intensity){}
inline Buff(BuffType type,float duration,float intensity,std::set<ItemAttribute> attr)
@ -68,6 +68,6 @@ struct Buff{
this->attr.insert(ItemAttribute::attributes.at(s));
}
}
inline Buff(BuffType type,float duration,float intensity,float timeBetweenTicks,std::function<void(Crawler*,int)>repeatAction)
inline Buff(BuffType type,float duration,float intensity,float timeBetweenTicks,std::function<void(AiL*,int)>repeatAction)
:type(type),duration(duration),intensity(intensity),nextTick(duration-timeBetweenTicks),timeBetweenTicks(timeBetweenTicks),repeatAction(repeatAction){}
};

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -36,7 +36,7 @@ All rights reserved.
*/
#pragma endregion
#include "Bullet.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "safemap.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -43,7 +43,7 @@ All rights reserved.
#include "DEFINES.h"
struct Bullet{
friend class Crawler;
friend class AiL;
vf2d vel;
vf2d pos;
float radius;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -4,4 +4,4 @@ debug.sh:8125f303032b6cbc137223df63d10096 -
lines.sh:3b907786f7fc9204025993016c9080de -
release.sh:b1ce8461a303e8e7aa9ed74259db3873 -
temp:d41d8cd98f00b204e9800998ecf8427e -
web.sh:cd3b8a99e208244dee7576bc23c0dc80 -
web.sh:1adf54f3c200922572a24573a0998110 -

@ -12,12 +12,12 @@ source ../emsdk/emsdk_env.sh
if [ ! -f "pixelGameEngine_wasm.o" ]
then
printf "Pixel Game Engine compile object missing. Compiling for the first time..."
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -c pixelGameEngine.cpp -o pixelGameEngine_wasm.o
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -s USE_FREETYPE=1 -c pixelGameEngine.cpp -o pixelGameEngine_wasm.o
fi
if [ -d "assets" ]; then
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html --preload-file ./assets
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -s USE_FREETYPE=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html --preload-file ./assets
else
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html
em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -s USE_FREETYPE=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html
fi
cp buildtemplate.html ${PROJECT_NAME}.html

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -38,7 +38,7 @@ All rights reserved.
#pragma once
#include "MenuLabel.h"
#include "DEFINES.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "util.h"
#include "Ability.h"
@ -51,7 +51,7 @@ public:
inline CharacterAbilityPreviewComponent(geom2d::rect<float>rect,Ability*ability)
:MenuLabel(rect,"",1,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND),ability(ability){}
protected:
virtual void inline Update(Crawler*game)override{
virtual void inline Update(AiL*game)override{
MenuLabel::Update(game);
}
virtual void inline DrawDecal(ViewPort&window,bool focused)override{

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "Menu.h"
#include "CharacterRotatingDisplay.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -40,7 +40,7 @@ All rights reserved.
#include "PopupMenuLabel.h"
#include "StatLabel.h"
#include "CharacterRotatingDisplay.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "ClassInfo.h"
#include "MenuItemItemButton.h"
#include "EquipSlotButton.h"
@ -133,26 +133,37 @@ void Menu::InitializeCharacterMenuWindow(){
ScrollableWindowComponent*equipList=Component<ScrollableWindowComponent>(data.component->parentMenu,"Equip List");
equipList->RemoveAllComponents();
for(int counter=0;const std::weak_ptr<Item>it:availableEquipment){
const static auto OppositeRingSlotDoesNotMatchCurrentEquip=[](RowItemDisplay*comp){
EquipSlot slot=EquipSlot(comp->I(Attribute::EQUIP_TYPE));
std::weak_ptr<Item>otherItem;
if(slot==EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
else
if(slot==EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
return ISBLANK(otherItem)||(&*comp->GetItem().lock()!=&*otherItem.lock());
};
auto equip=equipList->ADD("Equip Item "+std::to_string(counter),RowItemDisplay)({{2,2+counter*29.f},{120-15,28}},it,
[](MenuFuncData data){
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(data.component);
if(comp!=nullptr){
Inventory::EquipItem(comp->GetItem(),EquipSlot(comp->I(Attribute::EQUIP_TYPE)));
for(MenuComponent*button:((ScrollableWindowComponent*)data.parentComponent)->GetComponents()){
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(button);
if(comp!=nullptr){
comp->SetSelected(false);
}else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
if(OppositeRingSlotDoesNotMatchCurrentEquip(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->GetItem(),EquipSlot(comp->I(Attribute::EQUIP_TYPE)));
for(MenuComponent*button:((ScrollableWindowComponent*)data.parentComponent)->GetComponents()){
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(button);
if(comp!=nullptr){
comp->SetSelected(false);
}else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
}
}
comp->SetSelected(true);
for(int counter=0;const std::string&attribute:displayAttrs){
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute).Name())+" Label");
statDisplayLabel->SetStatChangeAmt(0);
}
MenuItemItemButton*equipButton=Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[data.parentComponent->I(A::INDEXED_THEME)]);
equipButton->SetItem(comp->GetItem(),false);
}
comp->SetSelected(true);
for(int counter=0;const std::string&attribute:displayAttrs){
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute).Name())+" Label");
statDisplayLabel->SetStatChangeAmt(0);
}
MenuItemItemButton*equipButton=Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[data.parentComponent->I(A::INDEXED_THEME)]);
equipButton->SetItem(comp->GetItem());
}else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
}
@ -169,17 +180,29 @@ void Menu::InitializeCharacterMenuWindow(){
for(const std::string&attribute:displayAttrs){
statsBeforeEquip.push_back(game->GetPlayer()->GetStat(attribute));
}
std::weak_ptr<Item>equippedItem=Inventory::GetEquip(slot);
Inventory::EquipItem(buttonItem,slot);
for(int counter=0;const std::string&attribute:displayAttrs){
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute).Name())+" Label");
int statChangeAmt=game->GetPlayer()->GetStat(attribute)-statsBeforeEquip[counter];
statDisplayLabel->SetStatChangeAmt(statChangeAmt);
counter++;
}
Inventory::UnequipItem(slot);
if(!ISBLANK(equippedItem)){
Inventory::EquipItem(equippedItem,slot);
std::weak_ptr<Item>otherItem;
if(slot==EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
else
if(slot==EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
if(OppositeRingSlotDoesNotMatchCurrentEquip(button)){ //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(buttonItem,slot);
for(int counter=0;const std::string&attribute:displayAttrs){
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute).Name())+" Label");
int statChangeAmt=game->GetPlayer()->GetStat(attribute)-statsBeforeEquip[counter];
statDisplayLabel->SetStatChangeAmt(statChangeAmt);
counter++;
}
Inventory::UnequipItem(slot);
if(!ISBLANK(equippedItem)){
Inventory::EquipItem(equippedItem,slot);
}
if(!ISBLANK(otherItem)){
if(slot==EquipSlot::RING1)Inventory::EquipItem(otherItem,EquipSlot::RING2);
else
if(slot==EquipSlot::RING2)Inventory::EquipItem(otherItem,EquipSlot::RING1);
}
}
}else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
@ -216,12 +239,17 @@ void Menu::InitializeCharacterMenuWindow(){
equipmentWindowOpened=true;
return true;
},[](MenuFuncData data){//On Mouse Hover
if(Component<MenuLabel>(data.component->parentMenu,"Item Equip Description")->GetLabel()!=""){
EquipSlot slot=DYNAMIC_CAST<EquipSlotButton*>(data.component)->GetSlot();
const std::weak_ptr<Item>equip=Inventory::GetEquip(slot);
if(!ISBLANK(equip)){
Component<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(false);
}
return true;
},[](MenuFuncData data){//On Mouse Out
if(Component<MenuLabel>(data.component->parentMenu,"Item Equip Description")->GetLabel()!=""&&!equipmentWindowOpened){
if(!equipmentWindowOpened){
Component<MenuLabel>(data.component->parentMenu,"Item Equip Description")->SetLabel("");
Component<MenuLabel>(data.component->parentMenu,"Item Equip Name")->Enable(false);
Component<MenuLabel>(data.component->parentMenu,"Item Equip Description")->Enable(false);
Component<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(true);
}
return true;
@ -248,9 +276,9 @@ void Menu::InitializeCharacterMenuWindow(){
characterMenuWindow->ADD("Back button",MenuComponent)({{windowSize.x/2-64,windowSize.y},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END;
auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuLabel)({{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuLabel)({{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuLabel)({{0,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
auto itemEquipNameDisplay=characterMenuWindow->ADD("Item Equip Name",MenuLabel)({{123,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
auto itemEquipNameDisplay=characterMenuWindow->ADD("Item Equip Name",MenuLabel)({{123,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
auto itemEquipDescriptionDisplay=characterMenuWindow->ADD("Item Equip Description",MenuLabel)({{123,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
itemNameDisplay->Enable(false);

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -38,7 +38,7 @@ All rights reserved.
#pragma once
#include "MenuComponent.h"
#include "DEFINES.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
INCLUDE_game
@ -55,7 +55,7 @@ public:
this->icon=icon;
}
protected:
virtual inline void Update(Crawler*game)override{
virtual inline void Update(AiL*game)override{
MenuComponent::Update(game);
timer+=game->GetElapsedTime();
if(timer>=2*PI){

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "BulletTypes.h"
#include "Effect.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "util.h"
#include "olcUTIL_Geometry2D.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -4,7 +4,7 @@
<Position X="3.5" Y="13.75" Width="1.5" />
<TypeIdentifier>
<HashCode>OihgwhJkUjgrCYAAVgEdFoQkBECSBhEDncMJIEmEYAg=</HashCode>
<FileName>Crawler.h</FileName>
<FileName>AdventuresInLestoria.h</FileName>
</TypeIdentifier>
</Class>
<Class Name="Effect" Collapsed="true">
@ -548,7 +548,7 @@
<Position X="19" Y="7.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAA=</HashCode>
<FileName>Crawler.h</FileName>
<FileName>AdventuresInLestoria.h</FileName>
</TypeIdentifier>
</Struct>
<Struct Name="Trapper" Collapsed="true">

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 164 KiB

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "Menu.h"
#include "MenuLabel.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -39,6 +39,7 @@ All rights reserved.
#include "olcUTIL_Geometry2D.h"
struct ConnectionPoint{
friend class State_OverworldMap;
geom2d::rect<float>rect;
std::string type;
std::string name;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "Menu.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "MenuItemItemButton.h"
#include "PlayerMoneyLabel.h"
#include "RowInventoryScrollableWindowComponent.h"
@ -123,7 +123,7 @@ void Menu::InitializeConsumableCraftingWindow(){
auto moneyIcon=consumableCraftingWindow->ADD("Money Icon",MenuIconButton)({moneyIconPos,{24,24}},GFX["money.png"].Decal(),DO_NOTHING,IconButtonAttr::NOT_SELECTABLE|IconButtonAttr::NO_OUTLINE|IconButtonAttr::NO_BACKGROUND)END;
std::string moneyText=std::to_string(game->GetPlayer()->GetMoney());
vf2d moneyTextSize=game->GetTextSizeProp(moneyText)*2;
auto moneyDisplay=consumableCraftingWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
auto moneyDisplay=consumableCraftingWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN|ComponentAttr::FIT_TO_LABEL)END;
moneyDisplay->SetRightAlignment(true);
Player::AddMoneyListener(moneyDisplay);
#pragma endregion

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -40,7 +40,7 @@ All rights reserved.
#define INCLUDE_MONSTER_LIST extern std::vector<Monster>MONSTER_LIST;
#define INCLUDE_SPAWNER_LIST extern std::vector<MonsterSpawner>SPAWNER_LIST;
#define INCLUDE_DAMAGENUMBER_LIST extern std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
#define INCLUDE_game extern Crawler*game;
#define INCLUDE_game extern AiL*game;
#define INCLUDE_MONSTER_DATA extern std::map<std::string,MonsterData>MONSTER_DATA;
#define INCLUDE_BULLET_LIST extern std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
#define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "DEFINES.h"
#include "Effect.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "safemap.h"
INCLUDE_ANIMATION_DATA

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -41,7 +41,7 @@ All rights reserved.
#include "olcUTIL_Animate2D.h"
struct Effect{
friend class Crawler;
friend class AiL;
vf2d pos={0,0};
float lifetime=0;
float fadeout=0;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -39,7 +39,7 @@ All rights reserved.
#include "olcPixelGameEngine.h"
struct Emitter{
friend class Crawler;
friend class AiL;
float frequency;
float timer;
float lastEmit=0;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -39,7 +39,7 @@ All rights reserved.
#include "State_OverworldMap.h"
#include "Menu.h"
#include "SpawnEncounterLabel.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "ScrollableWindowComponent.h"
#include "DEFINES.h"
#include "Error.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "BulletTypes.h"
#include "Effect.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "util.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -38,7 +38,7 @@ All rights reserved.
#pragma once
#include "MenuItemItemButton.h"
#include "DEFINES.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
INCLUDE_game
INCLUDE_ITEM_DATA
@ -53,10 +53,13 @@ public:
const std::weak_ptr<Item>equip=Inventory::GetEquip(slot);
if(!ISBLANK(equip)){
icon=const_cast<Decal*>(equip.lock()->Decal());
SetItem(equip);
itemRef=equip;
}else{
icon=nullptr;
SetItem(Item::BLANK);
itemRef=Item::BLANK;
}
}
inline const EquipSlot GetSlot()const{
return slot;
}
};

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "BulletTypes.h"
#include "Effect.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "util.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "GameState.h"
#include "State_GameRun.h"
#include "State_OverworldMap.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -40,7 +40,7 @@ All rights reserved.
#include <iostream>
#include "Error.h"
class Crawler;
class AiL;
namespace States{
enum State{
@ -53,7 +53,7 @@ namespace States{
};
class GameState{
friend class Crawler;
friend class AiL;
private:
static void _ChangeState(States::State newState);
public:
@ -62,7 +62,7 @@ public:
virtual ~GameState();
static void Initialize();
virtual void OnStateChange(GameState*prevState)=0;
virtual void OnUserUpdate(Crawler*game)=0;
virtual void Draw(Crawler*game)=0;
virtual void OnUserUpdate(AiL*game)=0;
virtual void Draw(AiL*game)=0;
static void ChangeState(States::State newState,float fadeOutDuration=0);
};

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "olcPixelGameEngine.h"
#include "safemap.h"
#include "Item.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -39,7 +39,7 @@ All rights reserved.
#include "Menu.h"
#include "MenuComponent.h"
#include "MenuItemButton.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "ScrollableWindowComponent.h"
#include "InventoryCreator.h"
@ -77,7 +77,7 @@ public:
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:ScrollableWindowComponent(rect,attributes),inventoryButtonHoverAction(inventoryButtonHoverAction),inventoryButtonMouseOutAction(inventoryButtonMouseOutAction),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),
options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive),addButtonOnSlotUpdate(creator.AddButtonOnSlotUpdate),onInventorySlotsUpdate(creator.InventorySlotsUpdate){}
virtual inline void Update(Crawler*game)override{
virtual inline void Update(AiL*game)override{
ScrollableWindowComponent::Update(game);
bool noneHovered=true;
for(MenuComponent*component:components){

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "Menu.h"
#include "MenuLabel.h"
@ -127,7 +127,7 @@ void Menu::InitializeInventoryWindow(){
auto moneyIcon=inventoryWindow->ADD("Money Icon",MenuIconButton)({moneyIconPos,{24,24}},GFX["money.png"].Decal(),DO_NOTHING,IconButtonAttr::NOT_SELECTABLE|IconButtonAttr::NO_OUTLINE|IconButtonAttr::NO_BACKGROUND)END;
std::string moneyText=std::to_string(game->GetPlayer()->GetMoney());
vf2d moneyTextSize=game->GetTextSizeProp(moneyText)*2;
auto moneyDisplay=inventoryWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,SHADOW|LEFT_ALIGN)END;
auto moneyDisplay=inventoryWindow->ADD("Money Label",PlayerMoneyLabel)({moneyIconPos-vf2d{2+moneyTextSize.x,-2},moneyTextSize},2,SHADOW|LEFT_ALIGN|FIT_TO_LABEL)END;
moneyDisplay->SetRightAlignment(true);
Player::AddMoneyListener(moneyDisplay);
#pragma endregion

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -38,11 +38,12 @@ All rights reserved.
#include "Item.h"
#include "safemap.h"
#include "DEFINES.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "Menu.h"
#include "Ability.h"
#include "AttributableStat.h"
#include <numeric>
#include "util.h"
INCLUDE_game
INCLUDE_DATA
@ -105,6 +106,8 @@ void ItemInfo::InitializeItems(){
std::vector<ItemAttribute>statValueList;
uint32_t sellValue=0;
uint32_t buyValue=0;
Stats minStats;
Stats maxStats;
bool useDuringCast=false;
for(auto&[itemKey,itemValue]:data[key].GetKeys()){
std::string keyName=itemKey;
@ -121,7 +124,7 @@ void ItemInfo::InitializeItems(){
castTime=float(data[key][keyName].GetReal());
}else
if(keyName=="Cooldown Time"){
castTime=float(data[key][keyName].GetReal());
cooldownTime=float(data[key][keyName].GetReal());
}else
if(keyName=="Slot"){
for(auto&val:data[key][keyName].GetValues()){
@ -129,7 +132,7 @@ void ItemInfo::InitializeItems(){
}
}else
if(keyName=="StatValues"){
for(int i=0;i<data[key]["StatValues"].GetValueCount();i++){
for(int i=0;i<data[key][keyName].GetValueCount();i++){
statValueList.push_back(ItemAttribute::Get(data[key]["StatValues"].GetString(i)));
}
}else
@ -147,13 +150,12 @@ void ItemInfo::InitializeItems(){
ItemInfo&it=ITEM_DATA[key];
if(statValueList.size()>0){
if(data[key].HasProperty("StatValues[0]")){ //This means this has enhancement levels.
EnhancementInfo enhancementStats;
for(int enhancementLevel=0;enhancementLevel<=10;enhancementLevel++){
uint8_t availableChapter=1;
datafile&dat=data[key]["StatValues["+std::to_string(enhancementLevel)+"]"];
int attrIndex=0;
for(ItemAttribute&attr:statValueList){
for(int attrIndex=0;ItemAttribute&attr:statValueList){
enhancementStats.SetAttribute(enhancementLevel,attr,dat.GetReal(attrIndex));
attrIndex++;
}
@ -192,6 +194,22 @@ void ItemInfo::InitializeItems(){
it.enhancement.SetCraftingRequirements(1,itemsRequired,goldCost,availableChapter);
}
if(data[key].HasProperty("MinStats")){
if(data[key]["MinStats"].GetValueCount()!=statValueList.size())ERR(std::format("MinStats attribute count does not match statValueList attribute count {}!={}",data[key]["MinStats"].GetValueCount(),statValueList.size()));
for(int attrCount=0;ItemAttribute&attr:statValueList){
minStats.A(attr)=data[key]["MinStats"].GetReal(attrCount);
attrCount++;
}
}
if(data[key].HasProperty("MaxStats")){
if(data[key]["MaxStats"].GetValueCount()!=statValueList.size())ERR(std::format("MaxStats attribute count does not match statValueList attribute count {}!={}",data[key]["MaxStats"].GetValueCount(),statValueList.size()));
for(int attrCount=0;ItemAttribute&attr:statValueList){
maxStats.A(attr)=data[key]["MaxStats"].GetReal(attrCount);
attrCount++;
}
}
if(data[key].HasProperty("MinStats")^data[key].HasProperty("MaxStats"))ERR("Only one of MinStats/MaxStats was provided! Both are required!");
if(scriptName!=""){
if(scriptName=="RestoreDuringCast"){
useDuringCast=true;
@ -228,6 +246,8 @@ void ItemInfo::InitializeItems(){
props.customProps=&data[key];
}
it.useFunc=scriptName;
it.minStats=minStats;
it.maxStats=maxStats;
#pragma region Equipment Category Verification Tests
int equipmentCategories=0;
@ -287,24 +307,24 @@ const uint32_t ItemProps::PropCount(const std::string&prop)const{
void ItemInfo::InitializeScripts(){
ITEM_SCRIPTS["Restore"]=[](Crawler*game,ItemProps props){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(Crawler*,int)>action){
ITEM_SCRIPTS["Restore"]=[](AiL*game,ItemProps props){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(AiL*,int)>action){
int restoreAmt=props.GetIntProp(propName);
action(game,restoreAmt);
if(restoreAmt>0&&props.PropCount(propName)==3){
game->GetPlayer()->AddBuff(RESTORATION,props.GetFloatProp(propName,2),restoreAmt,props.GetFloatProp(propName,1),action);
}
};
ParseItemScriptData("HP Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("HP Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->Heal(restoreAmt);
});
ParseItemScriptData("HP % Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("HP % Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->Heal(int(game->GetPlayer()->GetMaxHealth()*restoreAmt/100.0f));
});
ParseItemScriptData("MP Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("MP Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->RestoreMana(restoreAmt);
});
ParseItemScriptData("MP % Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("MP % Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->RestoreMana(int(game->GetPlayer()->GetMaxMana()*props.GetIntProp("MP % Restore")/100.f));
});
return true;
@ -316,7 +336,7 @@ void ItemInfo::InitializeScripts(){
}
}
ITEM_SCRIPTS["Buff"]=[](Crawler*game,ItemProps props){
ITEM_SCRIPTS["Buff"]=[](AiL*game,ItemProps props){
for(auto&[key,value]:ItemAttribute::attributes){
float intensity=props.GetFloatProp(key,0);
if(ItemAttribute::Get(key).DisplayAsPercent())intensity/=100;
@ -324,24 +344,24 @@ void ItemInfo::InitializeScripts(){
}
return true;
};
ITEM_SCRIPTS["RestoreDuringCast"]=[&](Crawler*game,ItemProps props){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(Crawler*,int)>action){
ITEM_SCRIPTS["RestoreDuringCast"]=[&](AiL*game,ItemProps props){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(AiL*,int)>action){
int restoreAmt=props.GetIntProp(propName);
action(game,restoreAmt);
if(restoreAmt>0&&props.PropCount(propName)==3){
game->GetPlayer()->AddBuff(RESTORATION_DURING_CAST,props.GetFloatProp(propName,2),restoreAmt,props.GetFloatProp(propName,1),action);
}
};
ParseItemScriptData("HP Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("HP Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->Heal(restoreAmt);
});
ParseItemScriptData("HP % Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("HP % Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->Heal(int(game->GetPlayer()->GetMaxHealth()*restoreAmt/100.0f));
});
ParseItemScriptData("MP Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("MP Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->RestoreMana(restoreAmt);
});
ParseItemScriptData("MP % Restore",[&](Crawler*game,int restoreAmt){
ParseItemScriptData("MP % Restore",[&](AiL*game,int restoreAmt){
game->GetPlayer()->RestoreMana(int(game->GetPlayer()->GetMaxMana()*props.GetIntProp("MP % Restore")/100.f));
});
return true;
@ -357,30 +377,38 @@ Item::Item()
Item::Item(uint32_t amt,IT item,uint8_t enhancementLevel)
:amt(amt),it(&ITEM_DATA.at(item)),enhancementLevel(enhancementLevel){}
void Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
std::weak_ptr<Item>Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
if(!ITEM_DATA.count(it))ERR("Item "<<std::quoted(it)<<" does not exist in Item Database!");
std::weak_ptr<Item>itemPtr;
if(ITEM_DATA[it].IsEquippable()){ //Do not stack equips!
for(uint32_t i=0;i<amt;i++){
InsertIntoSortedInv((*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second);
std::shared_ptr<Item>newItem=(*_inventory.insert({it,std::make_shared<Item>(1,it)})).second;
newItem->RandomizeStats();
InsertIntoSortedInv(newItem);
itemPtr=newItem;
}
goto SkipAddingStackableItem;
}
else
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if(!_inventory.count(it)){
InsertIntoSortedInv((*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second);
std::shared_ptr<Item>newItem=(*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second;
InsertIntoSortedInv(newItem);
itemPtr=newItem;
}else{
auto inventory=_inventory.equal_range(it);
std::accumulate(inventory.first,inventory.second,0,[&](int counter,std::pair<IT,std::shared_ptr<Item>>item){
if(std::accumulate(inventory.first,inventory.second,0,
[&](int counter,std::pair<IT,std::shared_ptr<Item>>item){
(*item.second).amt+=amt;
if(counter>=1)ERR("WARNING! We should not have more than 1 instance of a stackable item!");
return counter+1;
});
itemPtr=item.second;
return counter+1;})>1)ERR("WARNING! We should not have more than 1 instance of a stackable item!");
}
SkipAddingStackableItem:
InsertIntoStageInventoryCategory(it,amt,monsterDrop);
return itemPtr;
}
std::vector<std::shared_ptr<Item>>Inventory::CopyItem(IT it){
@ -422,6 +450,7 @@ bool Inventory::UseItem(IT it,uint32_t amt){
//Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint32_t amt){
if(amt==0)ERR("WARNING! Trying to remove zero of an item makes no sense.");
#pragma region Calculate Inventory to Manipulate
std::vector<std::shared_ptr<Item>>&inv=sortedInv.at(inventory);
bool eraseFromLootWindow=false;
@ -446,7 +475,7 @@ bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint3
}
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if (!itemAmt)return false;
if(!itemAmt)return false;
if (amt>=itemAmt){
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
@ -458,8 +487,19 @@ bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint3
Menu::InventorySlotsUpdated(inventory);
return true;
}else{
if(!eraseFromLootWindow){
itemRef.lock()->amt-=amt;
if(itemRef.lock()->IsEquippable()){ //Since equipment doesn't stack, if we have more than one piece we have to still remove that piece.
bool found=false;
size_t erased=std::erase_if(_inventory,[&](const std::pair<const IT,std::shared_ptr<Item>>data){
if(!found&&data.second==itemRef){
found=true;
return true;
}
return false;
});
if(erased!=1)ERR(std::format("Did not erase a single element, instead erased {} elements.",erased));
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
Menu::InventorySlotsUpdated(inventory);
return true;
}else{
itemRef.lock()->amt-=amt; //Don't touch the sorted inventory unless this is monster loot or stage loot because there's only "1" of this item in the entry list.
}
@ -543,6 +583,10 @@ const bool Item::IsEquippable()const{
const std::string Item::Description(CompactText compact)const{
std::string description=it->Description();
if(IsEquippable()){
if(HasRandomizedStats()){
description+='\n';
description+=randomizedStats.GetStatsString();
}
description+='\n';
description+=GetStats().GetStatsString(compact);
if(ItemSet()){
@ -627,11 +671,7 @@ const bool Item::IsBlank()const{
void Inventory::Clear(ITCategory itemCategory){
std::vector<std::shared_ptr<Item>>itemList=get(itemCategory); //We have to make a copy here because RemoveItem() will modify the list provided by get() inline.
for(std::shared_ptr<Item>&item:itemList){
size_t itemQuantity=GetItemCount(item->ActualName());//Normally we want to clear all the items that are actually in our inventory...But...
if(itemCategory=="Monster Loot"||itemCategory=="Stage Loot"){//These do not affect the actual inventory, we just clear the lists.
itemQuantity=item->Amt();
}
RemoveItem(item,itemCategory,uint32_t(itemQuantity));
RemoveItem(item,itemCategory,item->Amt());
}
}
@ -769,7 +809,7 @@ void ItemInfo::InitializeSets(){
}
}
const Stats&ItemInfo::GetStats(int enhancementLevel)const{
const Stats ItemInfo::GetStats(int enhancementLevel)const{
if(enhancement.size()<=enhancementLevel){
return {};
}
@ -893,7 +933,7 @@ void Item::SetAmt(uint32_t newAmt){
}
const std::weak_ptr<Item>Inventory::GetInventorySlot(ITCategory itemCategory,size_t slot){
return GetItem(get(itemCategory).at(slot)->ActualName())[0];
return get(itemCategory).at(slot);
}
bool Item::IsBlank(std::shared_ptr<Item>item){
@ -993,13 +1033,13 @@ const bool EnhancementInfo::CanBeEnhanced()const{
const bool ItemInfo::IsWeapon()const{
return slot==EquipSlot::WEAPON;
return slot&EquipSlot::WEAPON;
}
const bool ItemInfo::IsArmor()const{
return IsEquippable()&&!IsWeapon()&&!IsAccessory();
}
const bool ItemInfo::IsAccessory()const{
return slot==EquipSlot::RING1||slot==EquipSlot::RING2;
return slot&EquipSlot::RING1||slot&EquipSlot::RING2;
}
const bool Item::IsWeapon()const{
@ -1027,3 +1067,33 @@ const bool Item::EnhancementIsPossible()const{
const uint8_t EnhancementInfo::AvailableChapter()const{
return availableChapter;
}
const Stats&Item::RandomStats()const{
return randomizedStats;
};
void Item::RandomizeStats(){
randomizedStats=it->RandomizeStats();
};
const Stats ItemInfo::GetMinStats()const{
return minStats;
}
const Stats ItemInfo::GetMaxStats()const{
return maxStats;
}
Stats ItemInfo::RandomizeStats(){
Stats randomRolls;
for(auto&[attr,minVal]:minStats){
float diff=maxStats.A(attr)-minVal;
if(attr.ShowAsDecimal()){
randomRolls.A(attr)=util::random(diff)+minVal;
}else{
randomRolls.A(attr)=floor(util::random(diff+1)+minVal); //We must add 1 because we are going to floor the value to prevent the edges from having half as likely probability as all other numbers.
}
}
return randomRolls;
}
const bool Item::HasRandomizedStats()const{
return randomizedStats.size()>0;
}

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -48,14 +48,14 @@ All rights reserved.
#include "CraftingRequirement.h"
#include "FunctionPriming.h"
class Crawler;
class AiL;
class ItemInfo;
class ItemProps;
using IT=std::string;
using ITCategory=std::string;
using ItemScript=std::function<bool(Crawler*,ItemProps)>;
using ItemScript=std::function<bool(AiL*,ItemProps)>;
enum class EquipSlot{
HELMET= 0b0000'0001,
@ -102,7 +102,11 @@ public:
auto end()const{
return attributes.end();
}
const size_t size()const{
return attributes.size();
}
const std::string GetStatsString(CompactText compact=NON_COMPACT)const;
friend const bool operator==(const Stats&lhs,const Stats&rhs){return lhs.attributes==rhs.attributes;}
};
class Stats;
@ -150,8 +154,9 @@ public:
class Item{
friend class Inventory;
friend class Crawler;
friend class AiL;
friend class Menu;
friend class SaveFile;
friend void Merchant::PurchaseItem(IT item,uint32_t amt);
friend void Merchant::SellItem(std::weak_ptr<Item>,uint32_t amt);
private:
@ -159,10 +164,12 @@ private:
uint32_t amt;
uint8_t enhancementLevel;
ItemInfo*it;
Stats randomizedStats;
void SetAmt(uint32_t newAmt);
static ItemEnhancementFunctionPrimingData enhanceFunctionPrimed;
static int IsBlankStaticCallCounter;
const bool _IsBlank()const;
static ItemEnhancementFunctionPrimingData enhanceFunctionPrimed;
public:
Item();
Item(uint32_t amt,IT item,uint8_t enhancementLevel=0);
@ -200,14 +207,17 @@ public:
const uint32_t SellValue()const;
const bool CanBeSold()const;
const bool CanBePurchased()const;
const Stats&RandomStats()const;
void RandomizeStats();
const bool HasRandomizedStats()const;
const EnhancementInfo&GetEnhancementInfo()const;
//Use ISBLANK macro instead!! This should not be called directly!!
static bool IsBlank(std::shared_ptr<Item>item);
//Use ISBLANK macro instead!! This should not be called directly!!
static bool IsBlank(std::weak_ptr<Item>item);
friend const bool operator==(std::shared_ptr<Item>lhs,std::shared_ptr<Item>rhs){return lhs->it==rhs->it;};
friend const bool operator==(std::shared_ptr<Item>lhs,std::shared_ptr<Item>rhs){return lhs->it==rhs->it&&lhs->randomizedStats==rhs->randomizedStats;};
friend const bool operator==(std::shared_ptr<Item>lhs,const IT&rhs){return lhs->ActualName()==rhs;};
friend const bool operator==(std::weak_ptr<Item>lhs,std::weak_ptr<Item>rhs){return !lhs.expired()&&!rhs.expired()&&lhs.lock()->it==rhs.lock()->it;};
friend const bool operator==(std::weak_ptr<Item>lhs,std::weak_ptr<Item>rhs){return !lhs.expired()&&!rhs.expired()&&lhs.lock()->it==rhs.lock()->it&&lhs.lock()->randomizedStats==rhs.lock()->randomizedStats;};
friend const bool operator==(std::weak_ptr<Item>lhs,const IT&rhs){return !lhs.expired()&&lhs.lock()->ActualName()==rhs;};
friend const bool operator==(const IT&lhs,std::weak_ptr<Item>rhs){return operator==(rhs,lhs);};
friend const bool operator==(const IT&lhs,std::shared_ptr<Item>rhs){return operator==(rhs,lhs);};
@ -216,10 +226,11 @@ public:
class Inventory{
friend class ItemInfo;
friend class Item;
friend class SaveFile;
public:
static void AddItem(IT it,uint32_t amt=1,bool monsterDrop=false);
static std::weak_ptr<Item>AddItem(IT it,uint32_t amt=1,bool monsterDrop=false);
//Returns the actual amount available in your main inventory.
static uint32_t GetItemCount(IT it);
[[nodiscard]] static uint32_t GetItemCount(IT it);
static std::vector<std::shared_ptr<Item>>CopyItem(IT it);
static std::vector<std::weak_ptr<Item>>GetItem(IT it);
//Auto-executes its use function and removes the amt specified from the inventory. Multiple amounts will cause the item to execute its useFunc multiple times.
@ -284,6 +295,8 @@ class ItemInfo{
uint32_t sellValue=0;
//If true, this item's action is activated at the beginning of the cast instead of after the cast completes.
bool useDuringCast=false;
Stats minStats;
Stats maxStats;
private:
static void InitializeScripts();
static void InitializeSets();
@ -300,7 +313,7 @@ public:
For the useFunc, return true if the item can be used, false otherwise.
*/
const ItemScript&OnUseAction()const;
const Stats&GetStats(int enhancementLevel)const;
const Stats GetStats(int enhancementLevel)const;
const float CastTime()const;
const float CooldownTime()const;
const EquipSlot Slot()const;
@ -317,6 +330,9 @@ public:
const bool IsWeapon()const;
const bool IsArmor()const;
const bool IsAccessory()const;
const Stats GetMinStats()const;
const Stats GetMaxStats()const;
Stats RandomizeStats();
};
class ItemOverlay{

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "ItemDrop.h"
#include "olcUTIL_Geometry2D.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
INCLUDE_game
INCLUDE_GFX

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -38,10 +38,10 @@ All rights reserved.
#include "olcPixelGameEngine.h"
#include "Item.h"
#include "util.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
class ItemDrop{
friend class Crawler;
friend class AiL;
vf2d pos;
vf2d speed{};
float zSpeed=0;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "Menu.h"
#include "MenuLabel.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "Key.h"
#include "DEFINES.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
INCLUDE_game

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -36,7 +36,7 @@ All rights reserved.
*/
#pragma endregion
#include "Menu.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "MenuLabel.h"
#include "MenuComponent.h"
#include "InventoryScrollableWindowComponent.h"

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -37,7 +37,7 @@ All rights reserved.
#pragma endregion
#include "BulletTypes.h"
#include "Effect.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "Emitter.h"
#include "util.h"
@ -56,7 +56,7 @@ void LightningBolt::Update(float fElapsedTime){
if(lastParticleSpawn==0){
lastParticleSpawn="Wizard.Ability 2.ParticleFrequency"_F;
uint8_t brightness=uint8_t("Wizard.Ability 2.ParticleColorRange"_FRange);
switch(rand()%4){
switch(util::random()%4){
case 0:{
game->AddEffect(std::make_unique<Effect>(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"lightning_bolt_part1.png",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness}));
}break;

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -38,7 +38,7 @@ All rights reserved.
#include "Emitter.h"
#include "olcUTIL_Geometry2D.h"
#include "util.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
INCLUDE_game
@ -56,7 +56,7 @@ void LightningBoltEmitter::DrawLightningBolt(){
const int MAX_ITERATIONS=100;
geom2d::line<float>lineToTarget=geom2d::line<float>(startPos,endPos);
float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x);
float targetDist=lineToTarget.length()*util::random(0.5);
float targetDist=lineToTarget.length()*util::random(0.5f);
targetAngle+=util::random((PI/2))-PI/4;
geom2d::line<float>lightningLine=geom2d::line<float>(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist});
game->AddEffect(std::make_unique<Effect>(lightningLine.upoint(0),0,"chain_lightning.png",upperLevel,vf2d{lightningLine.length(),0.2f},0.2f,vf2d{},WHITE,targetAngle,0,true));
@ -65,7 +65,7 @@ void LightningBoltEmitter::DrawLightningBolt(){
while(iterations<MAX_ITERATIONS&&geom2d::line<float>(currentPos,endPos).length()>1){
geom2d::line<float>lineToTarget=geom2d::line<float>(currentPos,endPos);
float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x);
float targetDist=lineToTarget.length()*util::random(0.5);
float targetDist=lineToTarget.length()*util::random(0.5f);
targetAngle+=util::random((PI/2))-PI/4;
geom2d::line<float>lightningLine=geom2d::line<float>(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist});
game->AddEffect(std::make_unique<Effect>(lightningLine.upoint(0),0,"chain_lightning.png",upperLevel,vf2d{lightningLine.length(),0.2f},0.2f,vf2d{},WHITE,targetAngle,0,true));

@ -0,0 +1,103 @@
#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 © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#pragma once
#include "MenuComponent.h"
#include "ClassInfo.h"
INCLUDE_ANIMATION_DATA
class LoadFileButton:public MenuComponent{
double playTime=-1;
int chapter=-1;
int level=-1;
std::string className="";
std::string saveFileName="";
int saveFileID=-1;
float animationTime=0;
public:
inline LoadFileButton(geom2d::rect<float>rect,const utils::datafile&metadata,const int saveFileID,MenuFunc onClick,ButtonAttr attributes)
:MenuComponent(rect,"",onClick,attributes),playTime(metadata.GetReal(0U)),chapter(metadata.GetInt(1U)),level(metadata.GetInt(2U)),className(metadata.GetString(3U)),saveFileName(metadata.GetString(4U)),saveFileID(saveFileID){
showDefaultLabel=false;
}
inline void Update(AiL*game)override{
MenuComponent::Update(game);
if(playTime==-1){
grayedOut=true;
}
animationTime+=game->GetElapsedTime();
}
inline void DrawDecal(ViewPort&window,bool focused)override{
MenuComponent::DrawDecal(window,focused);
if(playTime==-1){
window.DrawShadowStringPropDecal(rect.pos+vf2d{2,2},"UNKNOWN");
}else{
window.DrawShadowStringPropDecal(rect.pos+vf2d{2,2},saveFileName);
const std::map<std::string,std::string>classAnimations={
{Warrior::name,Warrior::walk_s},
{Ranger::name,Ranger::walk_s},
{Wizard::name,Wizard::walk_s},
{Thief::name,Thief::walk_s},
{Trapper::name,Trapper::walk_s},
{Witch::name,Witch::walk_s},
};
std::string chapterText=std::format("Ch.{}",chapter);
vf2d chapterTextSize=game->GetTextSize(chapterText);
window.DrawShadowStringDecal(rect.pos+vf2d{rect.size.x-chapterTextSize.x-2,2},chapterText);
const Animate2D::Frame&frame=ANIMATION_DATA[classAnimations.at(className)].GetFrame(animationTime);
geom2d::rect<int>sprRect=frame.GetSourceRect();
window.DrawPartialDecal(rect.pos+vf2d{rect.size.x-26,rect.size.y-36},sprRect.size,frame.GetSourceImage()->Decal(),sprRect.pos,sprRect.size);
std::string levelClassText=std::format("Lv{} {}",level,className);
vf2d levelClassTextSize=game->GetTextSize(levelClassText);
window.DrawShadowStringDecal(rect.pos+vf2d{rect.size.x-levelClassTextSize.x-2,rect.size.y-10},levelClassText);
window.DrawShadowStringDecal(rect.pos+vf2d{2,12},util::timerStr(playTime));
}
}
inline const int&getSaveFileID()const{
return saveFileID;
}
};

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -30,19 +30,19 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Portions of this software are copyright © 2023 The FreeType
Portions of this software are copyright © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "DEFINES.h"
#include "Menu.h"
#include "MenuLabel.h"
#include "ScrollableWindowComponent.h"
INCLUDE_game
using A=Attribute;
void Menu::InitializeLoadGameWindow(){
Menu*loadGameWindow=CreateMenu(LOAD_GAME,CENTERED,vi2d{96,120});
void Menu::InitializeMainMenuWindow(){
Menu*mainMenuWindow=CreateMenu(MAIN_MENU,CENTERED,game->GetScreenSize()-vi2d{4,4});
loadGameWindow->ADD("Game Files Label",MenuLabel)({{-8,-12},{112,12}},"Load Game",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
loadGameWindow->ADD("Game Files List",ScrollableWindowComponent)({{-8,4},{112,116}})END;
loadGameWindow->ADD("Go Back Button",MenuComponent)({{24,124},{48,12}},"Back",[](MenuFuncData menu){Menu::CloseMenu();return true;})END;
}

@ -0,0 +1,84 @@
#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 © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "AdventuresInLestoria.h"
#include "DEFINES.h"
#include "Menu.h"
#include "MenuComponent.h"
#include "SaveFile.h"
INCLUDE_game
using A=Attribute;
void Menu::InitializeMainMenuWindow(){
Menu*mainMenuWindow=CreateMenu(MAIN_MENU,vi2d{132,120},vi2d{96,96});
mainMenuWindow->ADD("New Game Button",MenuComponent)({{12,4},{72,24}},"New Game",[&](MenuFuncData data){
game->TextEntryEnable(true);
#ifdef __EMSCRIPTEN__
data.menu.S(A::NEXT_MENU)="New Game";
if(SaveFile::GetUserID().length()==0){
Menu::OpenMenu(USER_ID);
}else{
Menu::OpenMenu(SAVE_FILE_NAME);
}
#else
Menu::OpenMenu(SAVE_FILE_NAME);
#endif
return true;
})END;
mainMenuWindow->ADD("Load Game Button",MenuComponent)({{12,36},{72,24}},"Load Game",[](MenuFuncData data){
#ifdef __EMSCRIPTEN__
data.menu.S(A::NEXT_MENU)="Load Game";
if(SaveFile::GetUserID().length()==0){
game->TextEntryEnable(true);
Menu::OpenMenu(USER_ID);
}else{
SaveFile::UpdateSaveGameData();
Menu::OpenMenu(LOAD_GAME);
}
#else
SaveFile::UpdateSaveGameData();
Menu::OpenMenu(LOAD_GAME);
#endif
return true;
})END;
mainMenuWindow->ADD("Quit Game Button",MenuComponent)({{12,68},{72,24}},"Quit Game",[](MenuFuncData data){
game->EndGame();
return true;
})END;
}

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -36,7 +36,7 @@ All rights reserved.
*/
#pragma endregion
#include "Map.h"
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "safemap.h"
INCLUDE_game

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -35,7 +35,7 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Crawler.h"
#include "AdventuresInLestoria.h"
#include "MenuComponent.h"
#include "DEFINES.h"
#include "safemap.h"
@ -111,6 +111,9 @@ void Menu::InitializeMenus(){
InitializeCraftItemWindow();
InitializeConsumableCraftingWindow();
InitializeConsumableCraftItemWindow();
InitializeSaveFileWindow();
InitializeLoadGameWindow();
InitializeUserIDWindow();
for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);type<MenuType::ENUM_END;type=MenuType(int(type+1))){
if(menus.count(type)==0){
@ -147,13 +150,13 @@ Menu*Menu::CreateMenu(MenuType type,vf2d pos,vf2d size){
return menus.at(type);
}
void Menu::CheckClickAndPerformMenuSelect(Crawler*game){
void Menu::CheckClickAndPerformMenuSelect(AiL*game){
if(game->GetMouse(Mouse::LEFT).bReleased||game->GetKey(SPACE).bReleased||game->GetKey(ENTER).bReleased){
MenuSelect(game);
}
}
void Menu::HoverMenuSelect(Crawler*game){
void Menu::HoverMenuSelect(AiL*game){
if(!game->IsFocused()||selection==vi2d{-1,-1}||buttons[selection.y][selection.x]->disabled)return;
if(buttons[selection.y][selection.x]->draggable){
if(buttonHoldTime<"ThemeGlobal.MenuHoldTime"_F){
@ -167,7 +170,7 @@ void Menu::HoverMenuSelect(Crawler*game){
}
}
void Menu::MenuSelect(Crawler*game){
void Menu::MenuSelect(AiL*game){
if(!game->IsFocused()||selection==vi2d{-1,-1}||(buttons[selection.y][selection.x]->disabled||buttons[selection.y][selection.x]->grayedOut))return;
bool buttonStillValid=buttons[selection.y][selection.x]->onClick(MenuFuncData{*this,game,buttons[selection.y][selection.x],(ScrollableWindowComponent*)buttons[selection.y][selection.x]->parentComponent});
if(buttonStillValid){
@ -181,7 +184,8 @@ void Menu::MenuSelect(Crawler*game){
}
}
void Menu::Update(Crawler*game){
void Menu::Update(AiL*game){
if(buttons.count(selection.y)==0)selection={-1,-1};
if(selection.x<0||selection.x>=buttons[selection.y].size()){selection={-1,-1};}
if(draggingComponent==nullptr){
@ -203,9 +207,11 @@ void Menu::Update(Crawler*game){
bool itemHovered=false;
if(!UsingMouseNavigation()){
if(selection!=vi2d{-1,-1}){
buttons[selection.y][selection.x]->hovered=true;
itemHovered=true;
if(!game->IsTextEntryEnabled()){
if(selection!=vi2d{-1,-1}){
buttons[selection.y][selection.x]->hovered=true;
itemHovered=true;
}
}
}else{
selection={-1,-1};
@ -244,12 +250,14 @@ void Menu::Update(Crawler*game){
};
if(!UsingMouseNavigation()){
if(game->GetKey(ENTER).bReleased||game->GetKey(SPACE).bReleased){
if(selectedComponent==nullptr){//Dropping over an empty area.
ClearDraggingComponent();
}else
if(selectedComponent->DropDraggableItem(draggingComponent)){
ClearDraggingComponent();
if(!game->IsTextEntryEnabled()){
if(game->GetKey(ENTER).bReleased||game->GetKey(SPACE).bReleased){
if(selectedComponent==nullptr){//Dropping over an empty area.
ClearDraggingComponent();
}else
if(selectedComponent->DropDraggableItem(draggingComponent)){
ClearDraggingComponent();
}
}
}
}else{
@ -264,7 +272,9 @@ void Menu::Update(Crawler*game){
}
}
KeyboardButtonNavigation(game,pos);
if(!game->IsTextEntryEnabled()){
KeyboardButtonNavigation(game,pos);
}
for(auto&[key,value]:buttons){
for(auto&button:value){
@ -292,7 +302,7 @@ void Menu::Update(Crawler*game){
}
};
void Menu::Draw(Crawler*game){
void Menu::Draw(AiL*game){
if(GetCurrentTheme().IsScaled()){
DrawScaledWindowBackground(game,pos,size,GetRenderColor());
}else{
@ -341,7 +351,7 @@ void Menu::OpenMenu(MenuType menu,bool cover){
stack.push_back(menus[menu]);
}
void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){
void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
vi2d prevSelection=selection;
if(game->GetKey(RIGHT).bPressed){
if(selection==vi2d{-1,-1})return;
@ -479,7 +489,7 @@ void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){
}
}
void Menu::DrawScaledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
void Menu::DrawScaledWindowBorder(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Upper-Left
@ -500,7 +510,7 @@ void Menu::DrawScaledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel rend
game->DrawPartialDecal(menuPos+vf2d{0,size.y},vf2d{size.x,patchSize.y},GetPatchPart(1,2).Decal(),{patchSize.x*1,patchSize.y*2},patchSize,renderColor);
}
void Menu::DrawTiledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
void Menu::DrawTiledWindowBorder(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Upper-Left
@ -521,7 +531,7 @@ void Menu::DrawTiledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel rende
game->DrawPartialDecal(menuPos+vf2d{0,size.y},vf2d{size.x,patchSize.y},GetPatchPart(1,2).Decal(),{0,0},vf2d{size.x,patchSize.y},renderColor);
}
void Menu::DrawScaledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
void Menu::DrawScaledWindowBackground(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Center
@ -533,7 +543,7 @@ void Menu::DrawScaledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel
}
}
void Menu::DrawTiledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
void Menu::DrawTiledWindowBackground(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Center
@ -695,7 +705,7 @@ void Menu::RecalculateComponentCount(){
componentCount=displayComponents.size()+buttons.size();
}
MenuType Menu::GetType(){
const MenuType Menu::GetType()const{
return type;
}
@ -710,3 +720,7 @@ void Menu::AddChapterListener(MenuComponent*component){
}
chapterListeners.push_back(component);
}
MenuFuncData::MenuFuncData(Menu&menu,AiL*const game,MenuComponent*const component,ScrollableWindowComponent*const parentComponent)
:menu(menu),game(game),component(component),parentComponent(parentComponent){}

@ -3,7 +3,7 @@
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
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:
@ -44,7 +44,7 @@ All rights reserved.
#include "olcUTIL_Geometry2D.h"
#include "olcPGEX_ViewPort.h"
class Crawler;
class AiL;
class MenuComponent;
class ScrollableWindowComponent;
@ -57,11 +57,9 @@ class ScrollableWindowComponent;
#define STARTING_DEPTH 999999
enum MenuType{
#pragma region Enum Start //DO NOT REMOVE
///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ENUM_START,///////////////////////////////
///////////////////////////////////////////////////////////
#pragma endregion
INVENTORY_CONSUMABLES,
CLASS_INFO,
CLASS_SELECTION,
@ -79,11 +77,12 @@ enum MenuType{
CRAFT_ITEM,
CRAFT_CONSUMABLE,
CONSUMABLE_CRAFT_ITEM,
#pragma region Enum End //DO NOT REMOVE
SAVE_FILE_NAME,
LOAD_GAME,
USER_ID,
///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
///////////////////////////////////////////////////////////
#pragma endregion
};
class Menu:public IAttributable{
@ -104,8 +103,11 @@ class Menu:public IAttributable{
static void InitializeCraftItemWindow();
static void InitializeConsumableCraftingWindow();
static void InitializeConsumableCraftItemWindow();
static void InitializeSaveFileWindow();
static void InitializeLoadGameWindow();
static void InitializeUserIDWindow();
friend class Crawler;
friend class AiL;
friend struct Player;
friend class ItemInfo;
friend class EntityStats;
@ -113,7 +115,7 @@ class Menu:public IAttributable{
float buttonHoldTime=0;
vi2d selection={-1,-1};
vi2d lastActiveMousePos={};
int componentCount;
int componentCount=0;
MenuComponent*draggingComponent=nullptr;
ViewPort window;
@ -181,8 +183,8 @@ public:
return component;
}
void Update(Crawler*game);
void Draw(Crawler*game);
void Update(AiL*game);
void Draw(AiL*game);
static void InitializeMenuListenerCategory(const std::string&category);
static void InitializeMenus();
static void LockInListeners();
@ -196,7 +198,7 @@ public:
static std::vector<MenuComponent*>unhandledComponents; //This list contains MenuComponents that are created and haven't been assigned via _AddComponent. If we get to the end of menu initialization and there are any components in this vector, we have leaked memory and will report this.
static const vf2d CENTERED;
static bool IsMenuOpen();
MenuType GetType();
const MenuType GetType()const;
safemap<std::string,MenuComponent*>components; //A friendly way to interrogate any component we are interested in.
std::vector<MenuComponent*>displayComponents; //Components that are only for displaying purposes.
static std::map<MenuType,Menu*>menus;
@ -228,17 +230,17 @@ private:
Menu(vf2d pos,vf2d size);
static MenuType lastMenuTypeCreated;
static std::string lastRegisteredComponent;
void HoverMenuSelect(Crawler*game);
void MenuSelect(Crawler*game);
void CheckClickAndPerformMenuSelect(Crawler*game);
void HoverMenuSelect(AiL*game);
void MenuSelect(AiL*game);
void CheckClickAndPerformMenuSelect(AiL*game);
//Mandatory before any menu operations! This creates and sets up the menu in memory.
static Menu*CreateMenu(MenuType type,vf2d pos,vf2d size);
void KeyboardButtonNavigation(Crawler*game,vf2d menuPos);
static void DrawScaledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
static void DrawTiledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
static void DrawScaledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
static void DrawTiledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
void KeyboardButtonNavigation(AiL*game,vf2d menuPos);
static void DrawScaledWindowBackground(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor);
static void DrawTiledWindowBackground(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor);
static void DrawScaledWindowBorder(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor);
static void DrawTiledWindowBorder(AiL*game,vf2d menuPos,vf2d size,Pixel renderColor);
//This triggers if we use a keyboard/controller input to try and select some off-screen menu item. We should ideally follow the menu cursor.
bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
@ -258,9 +260,10 @@ T*Component(MenuType menu,std::string componentName){
struct MenuFuncData{
Menu&menu;
Crawler*game;
MenuComponent*component;
ScrollableWindowComponent*parentComponent;
AiL*const game;
MenuComponent*const component;
ScrollableWindowComponent*const parentComponent=nullptr;
MenuFuncData(Menu&menu,AiL*const game,MenuComponent*const component,ScrollableWindowComponent*const parentComponent=nullptr);
};
using MenuFunc=std::function<bool(MenuFuncData)>;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save