diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build.yml similarity index 55% rename from .github/workflows/build_windows.yml rename to .github/workflows/build.yml index a3a21944..25ab6fac 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Windows Build +name: Build on: [push, pull_request] jobs: @@ -7,10 +7,11 @@ jobs: runs-on: ${{ matrix.os }} if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository strategy: + fail-fast: false matrix: include: - # - os: ubuntu-latest - # name: Linux + - os: ubuntu-latest + name: Linux # - os: macOS-latest # name: MacOS - os: windows-latest @@ -22,10 +23,16 @@ jobs: - name: Install Xorg lib if: matrix.name == 'Linux' run: | - sudo apt install -y libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev + sudo apt install -y libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev liblua5.3-dev - name: Update G++ if: matrix.name == 'Linux' run: sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100 + - name: Install Lua + if: matrix.name == 'Windows' + shell: bash + run: | + curl https://sourceforge.net/projects/luabinaries/files/5.4.2/Windows%20Libraries/Dynamic/lua-5.4.2_Win64_dll16_lib.zip/download -L > lua.zip + unzip lua - name: Build run: | mkdir build && cd build @@ -35,3 +42,15 @@ jobs: shell: bash if: matrix.name == 'Linux' run: test -f build/bomberman + - name: Archive production artifact for Windows binary + if: matrix.name == 'Windows' + uses: actions/upload-artifact@v1 + with: + name: BombermanWindows.exe + path: build/Debug/bomberman.exe + - name: Archive production artifact for Linux binary + if: matrix.name == 'Linux' + uses: actions/upload-artifact@v1 + with: + name: BombermanLinux + path: build/bomberman diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml deleted file mode 100644 index 9f352ac4..00000000 --- a/.github/workflows/build_linux.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Linux Build (Epitech Container) -on: [push, pull_request] - -jobs: - testbox: - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - runs-on: ubuntu-latest - container: - image: epitechcontent/epitest-docker:latest - steps: - - uses: actions/checkout@v2 - with: - submodules: true - - name: Build - run: | - mkdir build && cd build - cmake .. - cmake --build . - - name: CheckBinaryName - shell: bash - run: test -f build/bomberman \ No newline at end of file diff --git a/.github/workflows/build_web.yml b/.github/workflows/build_web.yml index 2b9a2f3e..88d67e18 100644 --- a/.github/workflows/build_web.yml +++ b/.github/workflows/build_web.yml @@ -9,6 +9,8 @@ jobs: - uses: actions/checkout@v1 with: submodules: true + - name: Install lua + run: sudo apt install -y liblua5.3-dev - name: Exec shell: bash run: ./build_web.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e87b9b9d..ae5f9a29 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: submodules: true - name: Install Xorg lib run: | - sudo apt install -y libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev + sudo apt install -y libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev liblua5.3-dev - name: Update G++ run: sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100 - name: Build diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cc80c6c..d7e36036 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,18 +3,20 @@ project(bomberman) set(CMAKE_CXX_STANDARD 20) -include_directories(bomberman lib/Ray/sources) -include_directories(bomberman lib/wal/sources) -include_directories(bomberman sources) +include_directories(lib/Ray/sources) +include_directories(lib/wal/sources) +include_directories(lib/LuaGate/sources) +include_directories(sources) add_subdirectory(${PROJECT_SOURCE_DIR}/lib/wal) add_subdirectory(${PROJECT_SOURCE_DIR}/lib/Ray) +add_subdirectory(${PROJECT_SOURCE_DIR}/lib/LuaGate) if (EMSCRIPTEN) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_DISABLE_EXCEPTION_CATCHING --shell-file ../sources/wasm/frontend.html --preload-file ../assets") - set(CMAKE_EXECUTABLE_SUFFIX ".html") + set(CMAKE_EXECUTABLE_SUFFIX ".html") endif () set(SOURCES @@ -79,6 +81,12 @@ set(SOURCES sources/Component/Collision/CollisionComponent.hpp sources/System/Collision/CollisionSystem.hpp sources/System/Collision/CollisionSystem.cpp + sources/Component/IAControllable/IAControllableComponent.hpp + sources/Component/IAControllable/IAControllableComponent.cpp + sources/System/IAControllable/IAControllableSystem.hpp + sources/System/IAControllable/IAControllableSystem.cpp + sources/Map/MapInfo.hpp + sources/Map/MapInfo.cpp sources/Component/Button/ButtonComponent.hpp sources/System/MenuControllable/MenuControllableSystem.cpp sources/System/MenuControllable/MenuControllableSystem.hpp @@ -134,33 +142,60 @@ set(SOURCES sources/Runner/PauseMenuScene.cpp sources/Runner/SettingsMenuScene.cpp sources/Runner/CreditScene.cpp + sources/Component/Score/ScoreComponent.cpp + sources/Component/Score/ScoreComponent.hpp + sources/System/Score/ScoreSystem.cpp + sources/System/Score/ScoreSystem.hpp + sources/System/EndCondition/EndConditionSystem.hpp + sources/System/EndCondition/EndConditionSystem.cpp sources/Runner/LobbyScene.cpp -) + sources/Runner/HowToPlayScene.cpp + sources/Runner/ScoreScene.cpp + sources/System/Shaders/ShaderSystem.cpp + sources/System/Shaders/ShaderSystem.hpp + sources/System/Shaders/ShaderModelSystem.cpp + sources/System/Shaders/ShaderModelSystem.hpp + sources/System/Shaders/ShaderDrawable2DSystem.cpp + sources/System/Shaders/ShaderDrawable2DSystem.hpp + sources/Component/Shaders/Items/BombExplosionShaderComponent.cpp + sources/Component/Shaders/Items/BombExplosionShaderComponent.hpp + sources/Component/Shaders/Items/WhiteShaderComponent.cpp + sources/Component/Shaders/Items/WhiteShaderComponent.hpp + sources/System/Timer/TimerUISystem.hpp + sources/System/Timer/TimerUISystem.cpp + sources/System/Bonus/BonusUISystem.hpp + sources/System/Bonus/BonusUISystem.cpp + sources/Component/Color/ColorComponent.hpp + sources/Component/Color/ColorComponent.cpp + sources/Component/Stat/StatComponent.cpp + sources/Component/Stat/StatComponent.hpp + ) + add_executable(bomberman - sources/main.cpp - ${SOURCES} -) -target_include_directories(bomberman PUBLIC sources) -target_link_libraries(bomberman PUBLIC wal ray) + sources/main.cpp + ${SOURCES} + ) +target_include_directories(bomberman PUBLIC sources LuaGate) +target_link_libraries(bomberman PUBLIC wal ray LuaGate) add_executable(unit_tests EXCLUDE_FROM_ALL - ${SOURCES} - tests/CacheTest.cpp - tests/EntityTests.cpp - tests/MainTest.cpp - tests/EngineTests.cpp - tests/CallbackTest.cpp - tests/MoveTests.cpp - tests/ViewTest.cpp - tests/CollisionTest.cpp -) -target_include_directories(unit_tests PUBLIC sources) -target_link_libraries(unit_tests PUBLIC wal ray) + ${SOURCES} + tests/CacheTest.cpp + tests/EntityTests.cpp + tests/MainTest.cpp + tests/EngineTests.cpp + tests/CallbackTest.cpp + tests/MoveTests.cpp + tests/ViewTest.cpp + tests/CollisionTest.cpp + ) +target_include_directories(unit_tests PUBLIC sources LuaGate) +target_link_libraries(unit_tests PUBLIC wal ray LuaGate) find_package(Catch2 QUIET) if (NOT Catch2_FOUND) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/lib/catch2) find_package(Catch2 REQUIRED) -endif() +endif () target_link_libraries(unit_tests PRIVATE Catch2::Catch2) diff --git a/Doxyfile b/Doxyfile index 12d9ca89..a8900e66 100644 --- a/Doxyfile +++ b/Doxyfile @@ -889,7 +889,6 @@ FILE_PATTERNS = *.c \ *.dox \ *.doc \ *.txt \ - *.py \ *.pyw \ *.f90 \ *.f95 \ @@ -919,6 +918,8 @@ RECURSIVE = YES EXCLUDE = */tests/* \ cmake-build-debug/* + build*/* + emsdk/* # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -1027,7 +1028,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing diff --git a/a b/a new file mode 100644 index 00000000..0e66280b --- /dev/null +++ b/a @@ -0,0 +1,266 @@ +WARNING: SHADER: [ID 5] Failed to find shader attribute: vertexTexCoord2 +WARNING: SHADER: [ID 5] Failed to find shader attribute: vertexNormal +WARNING: SHADER: [ID 5] Failed to find shader attribute: vertexTangent +WARNING: SHADER: [ID 5] Failed to find shader attribute: vertexColor +WARNING: SHADER: [ID 5] Failed to find shader uniform: view +WARNING: SHADER: [ID 5] Failed to find shader uniform: projection +WARNING: SHADER: [ID 5] Failed to find shader uniform: matNormal +WARNING: SHADER: [ID 5] Failed to find shader uniform: colDiffuse +WARNING: SHADER: [ID 5] Failed to find shader uniform: texture1 +WARNING: SHADER: [ID 5] Failed to find shader uniform: texture2 +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader attribute: vertexTexCoord2 +WARNING: SHADER: [ID 8] Failed to find shader attribute: vertexTangent +WARNING: SHADER: [ID 8] Failed to find shader attribute: vertexColor +WARNING: SHADER: [ID 8] Failed to find shader uniform: view +WARNING: SHADER: [ID 8] Failed to find shader uniform: projection +WARNING: SHADER: [ID 8] Failed to find shader uniform: matNormal +WARNING: SHADER: [ID 8] Failed to find shader uniform: colDiffuse +WARNING: SHADER: [ID 8] Failed to find shader uniform: texture1 +WARNING: SHADER: [ID 8] Failed to find shader uniform: texture2 +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 5] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask +WARNING: SHADER: [ID 8] Failed to find shader uniform: mask diff --git a/assets/ai_scripts/john.lua b/assets/ai_scripts/john.lua new file mode 100644 index 00000000..3363cb37 --- /dev/null +++ b/assets/ai_scripts/john.lua @@ -0,0 +1,330 @@ +------------ JOHN AI + +--[[ +Info available to the ai +mapinfo.player { x, y, z } +mapinfo.raw { {x, y, z, type }, ...} +mapinfo.dist { } +]] +------------ + +------ Debug variables +local debug = false + +if not debug then + log = function() end +else + log = function(a) + print(a) + end +end +----- Global variables +Dirs = {{x = 1, y = 0}, {x = -1, y = 0}, {x = 0, y = -1}, {x = 0, y = 1}} +MaxX = 0 +MaxY = 0 +Map = {} +Danger = {} +LastPos = nil + +----- Map functions +function PrintMap(map, MaxX, maxZ) + log("---------") + log("PRINT MAP") + log("---------") + for i=0,MaxX + 1 do + local s = "| " + for j=0,maxZ + 1 do + s = s .. tostring(map[i][j]) .. " | "; + end + log(s) + log(string.rep("-", (maxZ - 1) * 5 - 1)) + end +end + +function CreateMyMap(infos, MaxX, MaxY) + local map = {} + for i=0,MaxX + 1 do + map[i] = {} + for j=0,MaxY + 1 do + map[i][j] = 0 + end + end + for i, info in ipairs(infos) do + map[info.x][info.y] = info.type + end + --PrintMap(map, MaxX, MaxY) + return map +end + +function CreateDangerMap(dangers) + local danger = {} + for i=0,MaxX + 1 do + danger[i] = {} + for j=0,MaxY + 1 do + danger[i][j] = 0 + end + end + for i, zone in ipairs(dangers) do + if danger[math.floor(zone.x)] == nil then + danger[math.floor(zone.x)] = {} + end + danger[math.floor(zone.x)][math.floor(zone.y)] = math.floor(zone.level) + end + PrintMap(danger, MaxX, MaxY) + return danger +end + +function isInExplosionRange(x, y) + if Danger[x][y] > 0 then + return true + end + return false +end + +---- Pathfinding + +function setAdd(set, toAdd) + table.insert(set, toAdd) +end + +function setRemove(set, toRemove) + for i, node in ipairs(set) do + if node == toRemove then + set[i] = set[#set] + set[#set] = nil + break + end + end +end + +function not_in(set, node) + for _,value in pairs(set) do + if value.x == node.x and value.y == node.y then + return false + end + end + return true +end + + +function getNeighbors(node) + local neighbors = {} + for _, dir in ipairs(Dirs) do + local neighborX = node.x + dir.x + local neighborY = node.y + dir.y + if neighborY <= MaxY and neighborX <= MaxX then + if neighborY >= 0 and neighborX >= 0 then + if Map[neighborX][neighborY] == 0 and Danger[neighborX][neighborY] ~= 1 then + table.insert(neighbors, {x = neighborX, y = neighborY}) + end + end + end + end + if #neighbors == 0 and Danger[node.x][node.y] <= 1 then + for _, dir in ipairs(Dirs) do + local neighborX = node.x + dir.x + local neighborY = node.y + dir.y + if neighborY <= MaxY and neighborX <= MaxX then + if neighborY >= 0 and neighborX >= 0 then + if Map[neighborX][neighborY] == 0 then + table.insert(neighbors, {x = neighborX, y = neighborY}) + end + end + end + end + end + return neighbors +end + +function getLowestFromSet(set, f_score) + local lowest = 100000 + local best = nil + for _,node in ipairs(set) do + local score = f_score[node] + if score < lowest then + lowest = score + best = node + end + end + return best +end + +function fill_path(path, came_from, node) + if came_from[node] then + table.insert(path, 1, came_from[node]) + return fill_path(path, came_from, came_from[node]) + else + return path + end +end + +--A star search +function pathfind(root, target) + local closed = {} + local open = { root } + local came_from = {} + + local g_score = {} + local f_score = {} + + g_score[root] = 0 + f_score[root] = dist(root, target) + + while #open > 0 do + log("openset size") + log(#open) + local curr = getLowestFromSet(open, f_score) --get lowest node of openset + log("current node") + log(curr.x) + log(curr.y) + if curr.x == target.x and curr.y == target.y then + local path = fill_path({}, came_from, target) -- fill the path with came from + table.insert(path, target) + return path + end + setRemove(open, curr) -- remove curr from open + setAdd(closed, curr)-- add node to closed + log("closed set") + for i, c in ipairs(closed) do + log("member") + log(c.x) + log(c.y) + end + local neighbors = getNeighbors(curr) -- get neighbors of current + for _, neighbor in ipairs(neighbors) do + if not_in(closed, neighbor) then -- neighbor not in closed set + local try_g_score = g_score[curr] + 1 + if not_in(open, neighbor) or try_g_score < g_score[neighbor] then + came_from[neighbor] = curr + g_score[neighbor] = try_g_score + f_score[neighbor] = g_score[neighbor] + dist(neighbor, target) + if not_in(open, neighbor) then + setAdd(open, neighbor) + end + end + end + end + end + return {} +end + +function dist(nodeA, nodeB) + return math.sqrt(math.pow(nodeB.x - nodeA.x, 2) + math.pow(nodeB.y - nodeA.y, 2)) +end + +function getPathToSafeSpace(player) + local minXesc = (player.x - 3 < 0) and 0 or (player.x - 3); + local MaxXesc = (player.x + 3 > MaxX) and MaxX or (player.x + 3); + local minYesc = (player.y - 3 < 0) and 0 or (player.y - 3); + local MaxYesc = (player.y + 3 > MaxY) and MaxY or (player.y + 3); + + local minDist = 100000 + local res = {} + for i=minXesc,MaxXesc do + for j=minYesc, MaxYesc do + if Map[i][j] == 0 and Danger[i][j] == 0 then + local safe = {x = i, y = j} + local currDist = dist(player, safe) + if currDist < minDist then + minDist, res = currDist, safe + end + end + end + end + local path = pathfind(player, res) + return path +end + +function getNeighborAttack() +end + +function getPathToEnemy(player, enemies) + local minDist = 100000 + local res = {} + for _, enemy in ipairs(enemies) do + local currDist = dist(player, enemy) + if currDist < minDist then + minDist, res = currDist, enemy + end + end + local path = pathfind(player, res, getNeighborAttack) + return path +end + + +------ Update +function Update(mapinfo) + MaxX = 0 + MaxY = 0 + log("NEW FRAME") + for i, info in ipairs(mapinfo.raw) do + if info.x > MaxX then + MaxX = info.x + end + if info.y > MaxY then + MaxY = info.y + end + end + Map = CreateMyMap(mapinfo.raw, MaxX, MaxY) + Danger = CreateDangerMap(mapinfo.danger) + PrintMap(Danger, MaxX, MaxY) + log("Current player pos") + log(mapinfo.player.x) + log(mapinfo.player.y) + log("Rounded player pos") + local roundedPlayerPos = {x = math.floor(mapinfo.player.x+0.5), y = math.floor(mapinfo.player.y+0.5)} + log(roundedPlayerPos.x) + log(roundedPlayerPos.y) + log("Last target") + if LastTarget ~= nil then + log(LastTarget.x) + log(LastTarget.y) + if math.abs(LastTarget.x - mapinfo.player.x) <= 0.1 and math.abs(LastTarget.x - mapinfo.player.x) <= 0.1 then + LastTarget = nil + else + return (LastTarget.x - mapinfo.player.x), (LastTarget.y - mapinfo.player.y), false, false + end + else + log("No last target") + end + if (isInExplosionRange(roundedPlayerPos.x, roundedPlayerPos.y)) then + log("IN DANGER") + local pathToSafeSpace = getPathToSafeSpace(roundedPlayerPos) + log("PATH") + for i,p in ipairs(pathToSafeSpace) do + log(i) + log(p.x) + log(p.y) + end + if #pathToSafeSpace == 0 then + return 0, 0, false, false + end + local f = pathToSafeSpace[1] + log("first way of the path") + log(f.x) + log(f.y) + LastTarget = {x = f.x, y = f.y} + return f.x - roundedPlayerPos.x, f.y - roundedPlayerPos.y, false, false + else + local enemies = mapinfo.enemies + local pathToEnemy = getPathToEnemy(roundedPlayerPos, enemies) + if #pathToEnemy == 0 then + return 0, 0, false, false + end + local f = pathToEnemy[1] + log("first way of the path") + log(f.x) + log(f.y) + LastTarget = {x = f.x, y = f.y} + --pathfind to closest player + if LastPos == nil then + LastPos = {x = mapinfo.player.x, y = mapinfo.player.y} + else + if mapinfo.player.x == LastPos.x and mapinfo.player.y == LastPos.y then + return 0, 0, true, true + end + end + LastTarget = {x = f.x, y = f.y} + return f.x - roundedPlayerPos.x, f.y - roundedPlayerPos.y, false, false; + end +end \ No newline at end of file diff --git a/assets/ai_scripts/randboi.lua b/assets/ai_scripts/randboi.lua new file mode 100644 index 00000000..0979d7ae --- /dev/null +++ b/assets/ai_scripts/randboi.lua @@ -0,0 +1,14 @@ +math.randomseed(os.time()) + +function Update(mapinfo) + + local x = math.random() + local y = math.random() + if (math.random() < 0.5) then + x = x * -1 + end + if (math.random() < 0.5) then + y = y * -1 + end + return x, y, false, true; +end \ No newline at end of file diff --git a/assets/background_game.png b/assets/background_game.png new file mode 100644 index 00000000..22b4cd46 Binary files /dev/null and b/assets/background_game.png differ diff --git a/assets/buttons/button_htp.png b/assets/buttons/button_htp.png new file mode 100644 index 00000000..c54d0afd Binary files /dev/null and b/assets/buttons/button_htp.png differ diff --git a/assets/buttons/button_htp_hovered.png b/assets/buttons/button_htp_hovered.png new file mode 100644 index 00000000..227dcc7c Binary files /dev/null and b/assets/buttons/button_htp_hovered.png differ diff --git a/assets/game_background.png b/assets/game_background.png new file mode 100644 index 00000000..366ef882 Binary files /dev/null and b/assets/game_background.png differ diff --git a/assets/items/fireup.mtl b/assets/items/fireup.mtl index a90b6641..8c9f9b39 100644 --- a/assets/items/fireup.mtl +++ b/assets/items/fireup.mtl @@ -10,3 +10,4 @@ Ke 0.000000 0.000000 0.000000 Ni 1.000000 d 1.000000 illum 2 +map_Kd items.png diff --git a/assets/items/fireup.obj b/assets/items/fireup.obj index 8aefa489..2eab214a 100644 --- a/assets/items/fireup.obj +++ b/assets/items/fireup.obj @@ -26,18 +26,18 @@ v -0.401008 -0.084798 0.397024 v -0.401017 0.065157 0.400706 v -0.398980 -0.065157 -0.402734 v -0.398990 0.084798 -0.399052 -vt 0.001000 0.498000 -vt 0.001000 0.252000 -vt 0.124000 0.498000 -vt 0.124000 0.252000 +vt 0.001000 0.248000 +vt 0.001000 0.002000 +vt 0.124000 0.248000 +vt 0.124000 0.002000 vt 0.632244 0.754140 vt 0.648280 0.754140 vt 0.632244 0.996259 vt 0.648280 0.996259 -vt 0.124000 0.252000 -vt 0.124000 0.498000 -vt 0.001000 0.252000 -vt 0.001000 0.498000 +vt 0.124000 0.002000 +vt 0.124000 0.248000 +vt 0.001000 0.002000 +vt 0.001000 0.248000 vt 0.648280 0.996259 vt 0.632244 0.996259 vt 0.648280 0.754140 @@ -54,7 +54,7 @@ vn 0.0001 -0.9997 -0.0246 vn -0.0025 -0.0245 0.9997 vn -0.0001 0.9997 0.0246 vn 0.0025 0.0245 -0.9997 -vn 1.0000 0.0000 0.0025 +vn 1.0000 -0.0000 0.0025 vn -1.0000 0.0000 -0.0025 usemtl mat_map_ob000_item_007.005 s 1 diff --git a/assets/player/ui/blue.png b/assets/player/ui/blue.png new file mode 100644 index 00000000..5243a306 Binary files /dev/null and b/assets/player/ui/blue.png differ diff --git a/assets/player/ui/green.png b/assets/player/ui/green.png new file mode 100644 index 00000000..2a24f76c Binary files /dev/null and b/assets/player/ui/green.png differ diff --git a/assets/player/ui/red.png b/assets/player/ui/red.png new file mode 100644 index 00000000..ad00d65c Binary files /dev/null and b/assets/player/ui/red.png differ diff --git a/assets/player/ui/yellow.png b/assets/player/ui/yellow.png new file mode 100644 index 00000000..a06c28ea Binary files /dev/null and b/assets/player/ui/yellow.png differ diff --git a/assets/shaders/alpha.fs b/assets/shaders/alpha.fs new file mode 100644 index 00000000..85f2c56c --- /dev/null +++ b/assets/shaders/alpha.fs @@ -0,0 +1,28 @@ +#version 330 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; +uniform float alpha; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + + // Convert texel color to grayscale using NTSC conversion weights + + texelColor.a = alpha; + + gl_FragColor = texelColor; + // Calculate final fragment color + //gl_FragColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/assets/shaders/bomb.vs b/assets/shaders/bomb.vs new file mode 100644 index 00000000..26dd04b1 --- /dev/null +++ b/assets/shaders/bomb.vs @@ -0,0 +1,114 @@ +#version 100 + +// Classic Perlin 3D Noise +// by Stefan Gustavson +// +vec4 permute(vec4 x) { + return mod(((x * 34.0) + 1.0) * x, 289.0); +} +vec4 taylorInvSqrt(vec4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} +vec3 fade(vec3 t) { + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +float cnoise(vec3 P) { + vec3 Pi0 = floor(P); // Integer part for indexing + vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 + Pi0 = mod(Pi0, 289.0); + Pi1 = mod(Pi1, 289.0); + vec3 Pf0 = fract(P); // Fractional part for interpolation + vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 / 7.0; + vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 / 7.0; + vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x, gy0.x, gz0.x); + vec3 g100 = vec3(gx0.y, gy0.y, gz0.y); + vec3 g010 = vec3(gx0.z, gy0.z, gz0.z); + vec3 g110 = vec3(gx0.w, gy0.w, gz0.w); + vec3 g001 = vec3(gx1.x, gy1.x, gz1.x); + vec3 g101 = vec3(gx1.y, gy1.y, gz1.y); + vec3 g011 = vec3(gx1.z, gy1.z, gz1.z); + vec3 g111 = vec3(gx1.w, gy1.w, gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform float frame; +uniform vec3 center; + +uniform float radius; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// NOTE: Add here your custom variables + +void main() { + // Send vertex attributes to fragment shader + fragPosition = vertexPosition + vertexPosition * vec3(cnoise(vec3(vertexNormal + vec3(frame))) * 0.5); + fragColor = vertexColor; + fragNormal = vertexNormal; + fragTexCoord = vertexTexCoord; + // Calculate final vertex position + gl_Position = mvp * vec4(fragPosition , radius); + //gl_Position = vec4(vertexNormal, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/explosion.fs b/assets/shaders/explosion.fs new file mode 100644 index 00000000..bd97a93d --- /dev/null +++ b/assets/shaders/explosion.fs @@ -0,0 +1,26 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec3 fragPosition; +varying vec3 fragNormal; +varying vec2 fragTexCoord; + +uniform sampler2D texture0; +uniform float alpha; + +void main() { + // Texel color fetching from texture sampler + + // NOTE: Implement here your fragment shader code + vec4 tmp; + tmp.rgb = texture2D(texture0, fragTexCoord).rgb; + + + tmp.a = alpha; + + gl_FragColor = tmp; + //gl_FragColor = vec4(fragColor.r, fragColor.g, fragColor.b, alpha); + +} \ No newline at end of file diff --git a/assets/shaders/explosion.vs b/assets/shaders/explosion.vs new file mode 100644 index 00000000..26dd04b1 --- /dev/null +++ b/assets/shaders/explosion.vs @@ -0,0 +1,114 @@ +#version 100 + +// Classic Perlin 3D Noise +// by Stefan Gustavson +// +vec4 permute(vec4 x) { + return mod(((x * 34.0) + 1.0) * x, 289.0); +} +vec4 taylorInvSqrt(vec4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} +vec3 fade(vec3 t) { + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +float cnoise(vec3 P) { + vec3 Pi0 = floor(P); // Integer part for indexing + vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 + Pi0 = mod(Pi0, 289.0); + Pi1 = mod(Pi1, 289.0); + vec3 Pf0 = fract(P); // Fractional part for interpolation + vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 / 7.0; + vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 / 7.0; + vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x, gy0.x, gz0.x); + vec3 g100 = vec3(gx0.y, gy0.y, gz0.y); + vec3 g010 = vec3(gx0.z, gy0.z, gz0.z); + vec3 g110 = vec3(gx0.w, gy0.w, gz0.w); + vec3 g001 = vec3(gx1.x, gy1.x, gz1.x); + vec3 g101 = vec3(gx1.y, gy1.y, gz1.y); + vec3 g011 = vec3(gx1.z, gy1.z, gz1.z); + vec3 g111 = vec3(gx1.w, gy1.w, gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform float frame; +uniform vec3 center; + +uniform float radius; + +// Output vertex attributes (to fragment shader) +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +// NOTE: Add here your custom variables + +void main() { + // Send vertex attributes to fragment shader + fragPosition = vertexPosition + vertexPosition * vec3(cnoise(vec3(vertexNormal + vec3(frame))) * 0.5); + fragColor = vertexColor; + fragNormal = vertexNormal; + fragTexCoord = vertexTexCoord; + // Calculate final vertex position + gl_Position = mvp * vec4(fragPosition , radius); + //gl_Position = vec4(vertexNormal, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/white.fs b/assets/shaders/white.fs new file mode 100644 index 00000000..cde80534 --- /dev/null +++ b/assets/shaders/white.fs @@ -0,0 +1,34 @@ +#version 330 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; +uniform float white; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture2D(texture0, fragTexCoord); + + if (white > texelColor.r) + texelColor.r = white; + if (white > texelColor.g) + texelColor.g = white; + if (white > texelColor.b) + texelColor.b = white; + + // Convert texel color to grayscale using NTSC conversion weights + //float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); + + gl_FragColor = texelColor; + // Calculate final fragment color + //gl_FragColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/lib/LuaGate/CMakeLists.txt b/lib/LuaGate/CMakeLists.txt new file mode 100644 index 00000000..eb227570 --- /dev/null +++ b/lib/LuaGate/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.11) +set(CMAKE_CXX_STANDARD 20) +project(LuaGate) + +include_directories(sources) + +if (CMAKE_COMPILER_IS_GNUCXX) + set(GCC_COVERAGE_COMPILE_FLAGS "-Wall -Wextra -Werror -Wshadow") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}") +endif () + +set(HEADERS + sources/LuaGate.hpp +) + +set(SRC + sources/LuaGate.cpp +) + +include(FindLua) +if (NOT LUA_FOUND) + if (EXISTS ${CMAKE_SOURCE_DIR}/include/lua.hpp) + message("Using local lua") + set(LUA_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include/) + set(LUA_LIBRARIES ${CMAKE_SOURCE_DIR}/lua54.lib) + else() + message(FATAL_ERROR "Lua could not be found.") + endif() +endif() + +add_library(LuaGate STATIC ${SRC} ${HEADERS}) +target_include_directories(LuaGate PUBLIC ${LUA_INCLUDE_DIR}) +target_link_libraries(LuaGate ${LUA_LIBRARIES}) diff --git a/lib/LuaGate/sources/LuaGate.cpp b/lib/LuaGate/sources/LuaGate.cpp new file mode 100644 index 00000000..bb381901 --- /dev/null +++ b/lib/LuaGate/sources/LuaGate.cpp @@ -0,0 +1,97 @@ +// +// Created by Louis Auzuret on 10/06/21 +// + +#include "LuaGate.hpp" + +namespace LuaG +{ + State::State() + : _state(luaL_newstate()) + { + luaL_openlibs(_state); + } + + State::~State() + { + lua_close(_state); + } + + lua_State *State::getState(void) + { + return _state; + } + + void State::getGlobal(std::string str) + { + lua_getglobal(_state, str.c_str()); + } + + void State::dofile(std::string filepath) + { + luaL_dofile(_state, filepath.c_str()); + } + + void State::dostring(std::string str) + { + luaL_dostring(_state, str.c_str()); + } + + float State::getReturnNumber(void) + { + float res = 0; + + if (lua_isnil(_state, -1)) + return res; + if (!lua_isnumber(_state, -1)) + return res; + res = lua_tonumber(_state, -1); + lua_pop(_state, 1); + + return res; + } + + bool State::getReturnBool(void) + { + bool res = false; + + if (lua_isnil(_state, -1)) + return res; + if (!lua_isboolean(_state, -1)) + return res; + res = lua_toboolean(_state, -1); + lua_pop(_state, 1); + return res; + } + + bool State::callFunction(int nbParams, int nbReturns) + { + lua_pcall(_state, nbParams, nbReturns, 0); + return true; + } + + void State::setTable(void) + { + lua_settable(_state, -3); + } + + void State::push(float val) + { + lua_pushnumber(_state, val); + } + + void State::push(std::string str) + { + lua_pushstring(_state, str.c_str()); + } + + void State::newTable(void) + { + lua_newtable(_state); + } + + void State::popLast(void) + { + lua_pop(_state, -1); + } +} diff --git a/lib/LuaGate/sources/LuaGate.hpp b/lib/LuaGate/sources/LuaGate.hpp new file mode 100644 index 00000000..cf59833a --- /dev/null +++ b/lib/LuaGate/sources/LuaGate.hpp @@ -0,0 +1,64 @@ +// +// Created by Louis Auzuret on 10/06/21 +// + +#include +#include + +namespace LuaG +{ + class State + { + private: + //! @brief Lua state + lua_State *_state; + public: + //! @brief ctor + State(); + + //! @brief dtor + ~State(); + + //! @brief No copy constrructor + State(const State &) = delete; + + //! @brief No assign operator + State &operator=(const State &) = delete; + + //! @brief Get Lua state + lua_State *getState(void); + + //! @brief Get global value on top of the stack + void getGlobal(std::string str); + + //! @brief Execute a file in this state + void dofile(std::string filepath); + + //! @brief Execute a string in this state + void dostring(std::string str); + + //! @brief Get return Number + float getReturnNumber(void); + + //! @brief Get return Number + bool getReturnBool(void); + + //! @brief call a lua function + bool callFunction(int nbParams, int nbReturns); + + //! @brief setTable + void setTable(void); + + //! @brief push a number onto the lua stack + void push(float val); + + //! @brief push a string onto the lua stack + void push(std::string str); + + //! @brief Creates a new table at the top of the stack + void newTable(void); + + //! @brief Pop last value on the stack + void popLast(void); + }; +} \ No newline at end of file diff --git a/lib/Ray/CMakeLists.txt b/lib/Ray/CMakeLists.txt index 9a55f6be..11540070 100644 --- a/lib/Ray/CMakeLists.txt +++ b/lib/Ray/CMakeLists.txt @@ -57,6 +57,9 @@ set(HEADERS sources/Vector/Vector2.hpp sources/Vector/Vector3.hpp sources/Utils/Cache.hpp + sources/Meshes/AMesh.hpp + sources/Meshes/MeshSphere.hpp + sources/Shaders/Shaders.hpp ) set(SRC @@ -97,7 +100,10 @@ set(SRC sources/Model/ModelAnimations.cpp sources/Vector/Vector2.cpp sources/Vector/Vector3.cpp - sources/Shaders/Shaders.cpp sources/Shaders/Shaders.hpp) + sources/Shaders/Shaders.cpp + sources/Meshes/MeshSphere.cpp + sources/Meshes/AMesh.cpp + ) find_package(raylib QUIET) if (NOT raylib_FOUND) diff --git a/lib/Ray/sources/Drawables/2D/Rectangle.cpp b/lib/Ray/sources/Drawables/2D/Rectangle.cpp index 284e9b27..5ad4b674 100644 --- a/lib/Ray/sources/Drawables/2D/Rectangle.cpp +++ b/lib/Ray/sources/Drawables/2D/Rectangle.cpp @@ -12,8 +12,8 @@ namespace RAY::Drawables::Drawables2D { - Rectangle::Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color) : - ADrawable2D(position, color), _dimensions(dimensions) + Rectangle::Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color, float scale, float rotation) : + ADrawable2D(position, color, scale, rotation), _dimensions(dimensions) { } diff --git a/lib/Ray/sources/Drawables/2D/Rectangle.hpp b/lib/Ray/sources/Drawables/2D/Rectangle.hpp index 1a829ea2..7cd6caf8 100644 --- a/lib/Ray/sources/Drawables/2D/Rectangle.hpp +++ b/lib/Ray/sources/Drawables/2D/Rectangle.hpp @@ -11,76 +11,83 @@ #include #include "Drawables/ADrawable2D.hpp" -namespace RAY::Drawables::Drawables2D { +namespace RAY::Drawables::Drawables2D +{ //! @brief Rectangle in a two-dimensional space - class Rectangle: public ADrawable2D + class Rectangle : public ADrawable2D { - public: - //! @brief Rectangle constructor - //! @param position position of top-left point - //! @param dimensions dimensions of the rectangle - //! @param Color Color of the rectangle - Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color = WHITE); + public: + //! @brief Rectangle constructor + //! @param position position of top-left point + //! @param dimensions dimensions of the rectangle + //! @param Color Color of the rectangle + Rectangle(const Vector2 &position, + const Vector2 &dimensions, + const Color &color = WHITE, + float scale = 1, + float rotation = 0); - //! @brief Rectangle constructor - //! @param x x-position of top-left point - //! @param y y-position of top-left point - //! @param width width of the rectangle - //! @param length length of the rectangle - //! @param Color Color of the rectangle - Rectangle(int x, int y, int width, int height, const Color &color = WHITE); + //! @brief Rectangle constructor + //! @param x x-position of top-left point + //! @param y y-position of top-left point + //! @param width width of the rectangle + //! @param length length of the rectangle + //! @param Color Color of the rectangle + Rectangle(int x, int y, int width, int height, const Color &color = WHITE); - //! @brief A default copy constructor - Rectangle(const Rectangle &) = default; + //! @brief A default copy constructor + Rectangle(const Rectangle &) = default; - //! @brief A rectangle is assignable - Rectangle &operator=(const Rectangle &) = default; + //! @brief A rectangle is assignable + Rectangle &operator=(const Rectangle &) = default; - //! @brief A default destructor - ~Rectangle() override = default; + //! @brief A default destructor + ~Rectangle() override = default; - //! @return the dimensions of the rectangle - const Vector2 &getDimensions(void); + //! @return the dimensions of the rectangle + const Vector2 &getDimensions(void); - //! @return the width of the rectangle - float getWidth(void) const; + //! @return the width of the rectangle + float getWidth(void) const; - //! @return the height of the rectangle - float getHeight(void) const; + //! @return the height of the rectangle + float getHeight(void) const; - //! @brief set dimensions - Rectangle &setDimensions(const Vector2 &dimensions); + //! @brief set dimensions + Rectangle &setDimensions(const Vector2 &dimensions); - //! @brief increment width of the rectangle - //! @param width incrementer - Rectangle &incrementWidth(float width); + //! @brief increment width of the rectangle + //! @param width incrementer + Rectangle &incrementWidth(float width); - //! @brief increment height of the rectangle - //! @param height incrementer - Rectangle &incrementHeight(float height); + //! @brief increment height of the rectangle + //! @param height incrementer + Rectangle &incrementHeight(float height); - //! @brief set rectangle's height - //! @param height height of the rectangle - Rectangle &setHeight(float height); + //! @brief set rectangle's height + //! @param height height of the rectangle + Rectangle &setHeight(float height); - //! @brief set rectangle's width - //! @param width width of the rectangle - Rectangle &setWidth(float width); + //! @brief set rectangle's width + //! @param width width of the rectangle + Rectangle &setWidth(float width); - //! @brief set dimensions - Rectangle &setDimensions(float x, float y); + //! @brief set dimensions + Rectangle &setDimensions(float x, float y); - //! @brief Draw point on window - virtual void drawOn(RAY::Window &) override; - //! @brief Draw point on image - virtual void drawOn(RAY::Image &image) override; + //! @brief Draw point on window + virtual void drawOn(RAY::Window &) override; - protected: - //! @brief Diemnsions of the rectangle - Vector2 _dimensions; - - INTERNAL: - operator ::Rectangle() const; + //! @brief Draw point on image + virtual void drawOn(RAY::Image &image) override; + + protected: + //! @brief Diemnsions of the rectangle + Vector2 _dimensions; + + INTERNAL: + + operator ::Rectangle() const; }; }; diff --git a/lib/Ray/sources/Drawables/ADrawable2D.cpp b/lib/Ray/sources/Drawables/ADrawable2D.cpp index 0dd9804a..de5a0826 100644 --- a/lib/Ray/sources/Drawables/ADrawable2D.cpp +++ b/lib/Ray/sources/Drawables/ADrawable2D.cpp @@ -11,14 +11,20 @@ namespace RAY::Drawables { - ADrawable2D::ADrawable2D(const Vector2 &position, const RAY::Color &color) : - _position(position), _color(color) + ADrawable2D::ADrawable2D(const Vector2 &position, const RAY::Color &color, float scale, float rotation) : + _rotation(rotation), + _scale(scale), + _position(position), + _color(color) { } - ADrawable2D::ADrawable2D(int x, int y, const RAY::Color &color) : - _position(static_cast(x), static_cast(y)), _color(color) + ADrawable2D::ADrawable2D(int x, int y, const RAY::Color &color, float scale, float rotation) : + _rotation(rotation), + _scale(scale), + _position(static_cast(x), static_cast(y)), + _color(color) { } @@ -50,4 +56,14 @@ namespace RAY::Drawables this->_color = color; return *this; } + + float ADrawable2D::getScale() const + { + return this->_scale; + } + + void ADrawable2D::setScale(float scale) + { + this->_scale = scale; + } } \ No newline at end of file diff --git a/lib/Ray/sources/Drawables/ADrawable2D.hpp b/lib/Ray/sources/Drawables/ADrawable2D.hpp index f2364539..90988543 100644 --- a/lib/Ray/sources/Drawables/ADrawable2D.hpp +++ b/lib/Ray/sources/Drawables/ADrawable2D.hpp @@ -24,12 +24,12 @@ namespace RAY::Drawables { //! @brief ADrawable constructor //! @param poition position of top-left point //! @param Color Color of the color - ADrawable2D(const Vector2 &position, const RAY::Color &color); + ADrawable2D(const Vector2 &position, const RAY::Color &color, float scale = 1, float rotation = 0); //! @brief ADrawable constructor //! @param x x-position of top-left point //! @param y y-position of top-left point //! @param Color Color of the color - ADrawable2D(int x, int y, const RAY::Color &color); + ADrawable2D(int x, int y, const RAY::Color &color, float scale = 1, float rotation = 0); //! @brief A default copy constructor ADrawable2D(const ADrawable2D &) = default; @@ -58,7 +58,16 @@ namespace RAY::Drawables { //! @brief Draw drawble on image virtual void drawOn(RAY::Image &image) = 0; + //! @brief scale getter + float getScale() const; + //! @brief scale setters + void setScale(float scale); + protected: + //! @brief rotation + float _rotation = 0; + //! @brief scale + float _scale = 1; //! @brief Top-left position Vector2 _position; //! @brief Color of the ADrawable diff --git a/lib/Ray/sources/Drawables/Image.cpp b/lib/Ray/sources/Drawables/Image.cpp index a95246be..6b971898 100644 --- a/lib/Ray/sources/Drawables/Image.cpp +++ b/lib/Ray/sources/Drawables/Image.cpp @@ -11,7 +11,13 @@ #include "Exceptions/RayError.hpp" namespace RAY { - Cache<::Image> Image::_imagesCache(LoadImage, UnloadImage); + Cache<::Image> Image::_imagesCache([] (const char *str) { + ::Image image = LoadImage(str); + + if (image.data == nullptr) + throw Exception::ResourceNotFound(std::string(str)); + return image; + }, UnloadImage); Image::Image(const std::string &filename, bool lonely): Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE), diff --git a/lib/Ray/sources/Drawables/Image.hpp b/lib/Ray/sources/Drawables/Image.hpp index 7963328d..0ababe08 100644 --- a/lib/Ray/sources/Drawables/Image.hpp +++ b/lib/Ray/sources/Drawables/Image.hpp @@ -21,7 +21,7 @@ namespace RAY public: //! @brief Create an image, loading a file //! @param filename: path to file to load - //! @param lonely: should be set to true if the entity's loaded data must be independant from others + //! @param lonely: should be set to true if the entity's loaded data must be independent from others Image(const std::string &filename, bool lonely = false); //! @brief A default copy constructor diff --git a/lib/Ray/sources/Drawables/Texture.cpp b/lib/Ray/sources/Drawables/Texture.cpp index 936b399b..8114f98d 100644 --- a/lib/Ray/sources/Drawables/Texture.cpp +++ b/lib/Ray/sources/Drawables/Texture.cpp @@ -11,14 +11,20 @@ namespace RAY { - Cache<::Texture> Texture::_texturesCache(LoadTexture, UnloadTexture); + Cache<::Texture> Texture::_texturesCache([] (const char *str) { + ::Texture texture = LoadTexture(str); + + if (texture.id <= 0) + throw Exception::ResourceNotFound(std::string(str)); + return texture; + }, UnloadTexture); Texture::Texture() - : Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE) + : Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE, 1, 0), _resourcePath("") {} - Texture::Texture(const std::string &filename, bool lonely): - Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE), + Texture::Texture(const std::string &filename, bool lonely, float scale, float rotation): + Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE, scale, rotation), _texture(_texturesCache.fetch(filename, lonely)), _resourcePath(filename) { @@ -42,6 +48,11 @@ namespace RAY { return *this; } + const std::string &Texture::getResourcePath() const + { + return this->_resourcePath; + } + Texture::operator ::Texture() const { return *this->_texture; @@ -51,10 +62,7 @@ namespace RAY { { if (!this->_texture) return; - - float scale = this->_dimensions.x / this->_texture->width; - - DrawTextureEx(*this, this->_position, 0, scale, this->_color); + DrawTextureEx(*this, this->_position, this->_rotation, this->_scale, this->_color); } void Texture::unload() diff --git a/lib/Ray/sources/Drawables/Texture.hpp b/lib/Ray/sources/Drawables/Texture.hpp index 43126c9d..fe7fe9f1 100644 --- a/lib/Ray/sources/Drawables/Texture.hpp +++ b/lib/Ray/sources/Drawables/Texture.hpp @@ -21,7 +21,7 @@ namespace RAY //! @brief Create an texture, loading a file //! @param filename: path to file to load //! @param lonely: should be set to true if the entity's loaded data must be independant from others - explicit Texture(const std::string &filename, bool lonely = false); + explicit Texture(const std::string &filename, bool lonely = false, float scale = 1, float rotation = 0); //! @brief Create an empty texture Texture(); @@ -47,6 +47,9 @@ namespace RAY //! @brief Unload the current texture (calls to drawOn will no-op). void unload(); + //! @return path of loaded texture + const std::string &getResourcePath() const; + protected: private: //! @brief Texture, really, that's just it... diff --git a/lib/Ray/sources/Exceptions/RayError.cpp b/lib/Ray/sources/Exceptions/RayError.cpp index a4de1200..ee0d4fa7 100644 --- a/lib/Ray/sources/Exceptions/RayError.cpp +++ b/lib/Ray/sources/Exceptions/RayError.cpp @@ -26,3 +26,8 @@ RAY::Exception::WrongInputError::WrongInputError(const std::string &what): RayError(what) { } + +RAY::Exception::ResourceNotFound::ResourceNotFound(const std::string &path): + RayError(path + " couldn't be loaded") +{ +} diff --git a/lib/Ray/sources/Exceptions/RayError.hpp b/lib/Ray/sources/Exceptions/RayError.hpp index 158640d6..43c5590f 100644 --- a/lib/Ray/sources/Exceptions/RayError.hpp +++ b/lib/Ray/sources/Exceptions/RayError.hpp @@ -76,6 +76,23 @@ namespace RAY::Exception { //! @brief A default assignment operator WrongInputError &operator=(const WrongInputError &) = default; }; + + //! @brief exception used when a resource is not found + class ResourceNotFound: public RayError { + public: + //! @brief Create a new exception instance + //! @param path path of the un-loadable path + explicit ResourceNotFound(const std::string &path); + + //! @brief A default destructor + ~ResourceNotFound() override = default; + + //! @brief An exception is copy constructable + ResourceNotFound(const ResourceNotFound &) = default; + + //! @brief A default assignment operator + ResourceNotFound &operator=(const ResourceNotFound &) = default; + }; } #endif /* !RAYERROR_HPP_ */ diff --git a/lib/Ray/sources/Font.cpp b/lib/Ray/sources/Font.cpp index 89bf9517..50bb26a8 100644 --- a/lib/Ray/sources/Font.cpp +++ b/lib/Ray/sources/Font.cpp @@ -7,7 +7,13 @@ #include "Font.hpp" -RAY::Cache<::Font> RAY::Font::_fontsCache(LoadFont, UnloadFont); +RAY::Cache<::Font> RAY::Font::_fontsCache([] (const char *str) { + ::Font font = LoadFont(str); + + if (font.texture.id <= 0) + throw Exception::ResourceNotFound(std::string(str)); + return font; + }, UnloadFont); RAY::Font::Font(const std::string &filename, bool lonely): _font(_fontsCache.fetch(filename, lonely)) diff --git a/lib/Ray/sources/Meshes/AMesh.cpp b/lib/Ray/sources/Meshes/AMesh.cpp new file mode 100644 index 00000000..9a76e90e --- /dev/null +++ b/lib/Ray/sources/Meshes/AMesh.cpp @@ -0,0 +1,13 @@ +// +// Created by cbihan on 16/06/2021. +// + +#include "AMesh.hpp" + +namespace RAY::Mesh +{ + std::shared_ptr<::Mesh> RAY::Mesh::AMesh::getRaylibMesh() const + { + return this->_raylibMesh; + } +} \ No newline at end of file diff --git a/lib/Ray/sources/Meshes/AMesh.hpp b/lib/Ray/sources/Meshes/AMesh.hpp new file mode 100644 index 00000000..278552ec --- /dev/null +++ b/lib/Ray/sources/Meshes/AMesh.hpp @@ -0,0 +1,28 @@ +// +// Created by cbihan on 16/06/2021. +// + +#pragma once + +#include +#include + +namespace RAY::Mesh +{ + class AMesh + { + protected: + std::shared_ptr<::Mesh> _raylibMesh; + + INTERNAL: + //! @brief getter for _raylibMesh + std::shared_ptr<::Mesh> getRaylibMesh() const; + + public: + + //! @brief dtor + virtual ~AMesh() = default; + + }; + +} \ No newline at end of file diff --git a/lib/Ray/sources/Meshes/MeshSphere.cpp b/lib/Ray/sources/Meshes/MeshSphere.cpp new file mode 100644 index 00000000..349787c0 --- /dev/null +++ b/lib/Ray/sources/Meshes/MeshSphere.cpp @@ -0,0 +1,16 @@ +// +// Created by cbihan on 16/06/2021. +// + +#include "MeshSphere.hpp" + +namespace RAY::Mesh +{ + MeshSphere::MeshSphere(float radius_arg, int rings_arg, int slices_arg) : + radius(radius_arg), + rings(rings_arg), + slices(slices_arg) + { + this->_raylibMesh = std::make_shared<::Mesh>(GenMeshSphere(radius_arg, rings_arg, slices_arg)); + } +} \ No newline at end of file diff --git a/lib/Ray/sources/Meshes/MeshSphere.hpp b/lib/Ray/sources/Meshes/MeshSphere.hpp new file mode 100644 index 00000000..b8aa1c75 --- /dev/null +++ b/lib/Ray/sources/Meshes/MeshSphere.hpp @@ -0,0 +1,35 @@ +// +// Created by cbihan on 16/06/2021. +// + +#pragma once + +#include +#include "AMesh.hpp" +#include + +namespace RAY::Mesh +{ + class MeshSphere : public AMesh + { + public: + //! @brief radius + float radius; + //! @brief rings + int rings; + //! @brief slices + int slices; + + + //! @brief ctor + MeshSphere(float radius_arg, int rings_arg, int slices_arg); + //! @brief copy ctor + MeshSphere(const MeshSphere &) = default; + //! @brief dtor + ~MeshSphere() = default; + //! @brief assignment operator + MeshSphere &operator=(const MeshSphere &) = default; + + }; + +} diff --git a/lib/Ray/sources/Model/Model.cpp b/lib/Ray/sources/Model/Model.cpp index fefa29ea..59a508c6 100644 --- a/lib/Ray/sources/Model/Model.cpp +++ b/lib/Ray/sources/Model/Model.cpp @@ -13,7 +13,13 @@ namespace RAY::Drawables::Drawables3D { - RAY::Cache<::Model> Model::_modelsCache(LoadModel, UnloadModel); + RAY::Cache<::Model> Model::_modelsCache([] (const char *str) { + ::Model model = LoadModel(str); + + if (model.meshCount == 0) + throw Exception::ResourceNotFound(std::string(str)); + return model; + }, UnloadModel); Model::Model(const std::string &filename, bool lonely, @@ -32,10 +38,20 @@ namespace RAY::Drawables::Drawables3D this->setTextureToMaterial(texture->first, texture->second); } - Model::Model(const Mesh &mesh) - : ADrawable3D({0, 0, 0}, WHITE), - _model(std::make_shared<::Model>(LoadModelFromMesh(mesh))) + Model::Model(const Mesh::AMesh &mesh, + std::optional> texture, + const RAY::Vector3 &scale, + const RAY::Vector3 &position, + const RAY::Vector3 &rotationAxis, + float rotationAngle) + : ADrawable3D(position, WHITE), + _model(std::make_shared<::Model>(LoadModelFromMesh(*mesh.getRaylibMesh()))), + _rotationAxis(rotationAxis), + _rotationAngle(rotationAngle), + _scale(scale) { + if (texture.has_value()) + this->setTextureToMaterial(texture->first, texture->second); } bool Model::unloadKeepMeshes() @@ -61,6 +77,11 @@ namespace RAY::Drawables::Drawables3D return true; } + Texture &Model::getTextureByMaterial(MaterialType materialType) + { + return this->_textureList[materialType]; + } + Model::operator ::Model() const { return *this->_model; diff --git a/lib/Ray/sources/Model/Model.hpp b/lib/Ray/sources/Model/Model.hpp index 2bf6cf47..1d44352e 100644 --- a/lib/Ray/sources/Model/Model.hpp +++ b/lib/Ray/sources/Model/Model.hpp @@ -13,6 +13,7 @@ #include "Model/ModelAnimation.hpp" #include "Shaders/Shaders.hpp" #include +#include "Meshes/AMesh.hpp" #include #include #include "Utils/Cache.hpp" @@ -36,7 +37,12 @@ namespace RAY::Drawables::Drawables3D { //! @brief Create an model, loading a file //! @param mesh: mesh to load - Model(const Mesh &mesh); + Model(const Mesh::AMesh &mesh, + std::optional> texture = std::nullopt, + const RAY::Vector3 &scale = RAY::Vector3(1, 1, 1), + const RAY::Vector3 &position = {0, 0, 0}, + const RAY::Vector3 &rotationAxis = RAY::Vector3(0, 1, 0), + float rotationAngle = 0); //! @brief A copy constructor Model(const Model &model) = default; @@ -90,6 +96,10 @@ namespace RAY::Drawables::Drawables3D { //! @brief Draw model's wires on window void drawWiresOn(RAY::Window &) override; + //! @param materialType type of material + //! @return texture + Texture &getTextureByMaterial(MaterialType materialType); + private: //! @brief Raw data from raylib std::shared_ptr<::Model> _model; diff --git a/lib/Ray/sources/Model/ModelAnimations.cpp b/lib/Ray/sources/Model/ModelAnimations.cpp index 6d41832d..b1eedebc 100644 --- a/lib/Ray/sources/Model/ModelAnimations.cpp +++ b/lib/Ray/sources/Model/ModelAnimations.cpp @@ -7,7 +7,13 @@ #include "Model/ModelAnimations.hpp" -RAY::Cache<::ModelAnimation> RAY::ModelAnimations::_animationsCache(LoadModelAnimations, UnloadModelAnimations); +RAY::Cache<::ModelAnimation> RAY::ModelAnimations::_animationsCache([] (const char *str, int *counter) { + ::ModelAnimation *modelanimations = LoadModelAnimations(str, counter); + + if (modelanimations == nullptr) + throw Exception::ResourceNotFound(std::string(str)); + return modelanimations; + }, UnloadModelAnimations); RAY::ModelAnimations::ModelAnimations(const std::string &filePath): _animationsPtr(_animationsCache.fetch(filePath, &this->_animationCount)), diff --git a/lib/Ray/sources/Shaders/Shaders.cpp b/lib/Ray/sources/Shaders/Shaders.cpp index 435b4f72..0def3c96 100644 --- a/lib/Ray/sources/Shaders/Shaders.cpp +++ b/lib/Ray/sources/Shaders/Shaders.cpp @@ -12,11 +12,12 @@ namespace RAY Cache<::Shader> Shader::_shadersCache(LoadShader, UnloadShader); - Shader::Shader(const std::string &vertexFile, const std::string &fragmentFile) + Shader::Shader(const std::string &vertexFile, const std::string &fragmentFile, bool lonely) : _vertexFile(vertexFile), _fragmentFile(fragmentFile), - _rayLibShader(_shadersCache.fetch(vertexFile, fragmentFile)) + _rayLibShader(_shadersCache.fetch(vertexFile, fragmentFile, lonely)) { + this->_rayLibShader->locs[SHADER_LOC_MAP_EMISSION] = GetShaderLocation(*this->_rayLibShader, "mask"); } const std::shared_ptr<::Shader> &Shader::getShaderPtr() const @@ -37,6 +38,19 @@ namespace RAY SetShaderValue(*this->_rayLibShader, this->_shaderIndexVars[varName], &value, SHADER_UNIFORM_FLOAT); } + void Shader::setShaderUniformVar(const std::string &varName, int value) + { + if (this->_shaderIndexVars.find(varName) == this->_shaderIndexVars.end()) { + int varShaderIndex = GetShaderLocation(*this->_rayLibShader, varName.c_str()); + + if (varShaderIndex < 0) { + throw Exception::WrongInputError("The loaded shader doesn't have a variable called: " + varName); + } + this->_shaderIndexVars[varName] = varShaderIndex; + } + SetShaderValue(*this->_rayLibShader, this->_shaderIndexVars[varName], &value, SHADER_UNIFORM_INT); + } + void Shader::BeginUsingCustomShader(Shader &shader) { BeginShaderMode(*shader.getShaderPtr()); diff --git a/lib/Ray/sources/Shaders/Shaders.hpp b/lib/Ray/sources/Shaders/Shaders.hpp index 529eea64..20231ea7 100644 --- a/lib/Ray/sources/Shaders/Shaders.hpp +++ b/lib/Ray/sources/Shaders/Shaders.hpp @@ -42,8 +42,14 @@ namespace RAY //! @note Throw if the var is not found void setShaderUniformVar(const std::string &varName, float value); + //! @brief The set var for float values + //! @note Throw if the var is not found + void setShaderUniformVar(const std::string &varName, int value); + + void setLocation(::ShaderLocationIndex, const std::string &name); + //! @brief ctor if no vertexfile in needed set it to nullptr - Shader(const std::string &vertexFile, const std::string &fragmentFile); + Shader(const std::string &vertexFile, const std::string &fragmentFile, bool lonely = false); //! @brief Default copy ctor Shader(const Shader &) = default; //! @brief dtor diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp index beb1ff89..f7433c17 100644 --- a/lib/Ray/sources/Utils/Cache.hpp +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -45,7 +45,7 @@ namespace RAY { this->_cache.emplace(path, std::vector>()); std::vector> &matchingDataVector = this->_cache.at(path); - if (matchingDataVector.size()) { + if (!matchingDataVector.empty()) { for (std::shared_ptr &i: matchingDataVector) { if (!lonely) return i; @@ -117,23 +117,34 @@ namespace RAY { _dataLoader(std::move(dataLoader)), _dataUnloader(std::move(dataUnloader)) {}; - std::shared_ptr<::Shader> fetch(const std::string &vertexFile, const std::string &fragmentFile) + std::shared_ptr<::Shader> fetch(const std::string &vertexFile, const std::string &fragmentFile, bool lonely = false) { const std::string index = vertexFile + fragmentFile; if (vertexFile.empty() && fragmentFile.empty()) { throw RAY::Exception::WrongInputError(); } - if (this->_cache.find(index) != this->_cache.end()) - return this->_cache[index]; + if (!this->_cache.contains(index)) { + this->_cache.emplace(index, std::vector>()); + } + std::vector> &matchingDataVector = this->_cache.at(index); - this->_cache.emplace(index, std::shared_ptr<::Shader>( + if (!matchingDataVector.empty()) { + for (std::shared_ptr<::Shader> &i: matchingDataVector) { + if (!lonely) + return i; + if (lonely && i.use_count() == 1) + return i; + } + } + + matchingDataVector.emplace_back(std::shared_ptr<::Shader>( new ::Shader( this->_dataLoader(vertexFile.empty() ? nullptr : vertexFile.c_str(), fragmentFile.c_str())), [this](::Shader *p) { this->_dataUnloader(*p); })); - return this->_cache[index]; + return matchingDataVector.back(); }; private: //! @brief function to call to load data @@ -143,6 +154,6 @@ namespace RAY { std::function _dataUnloader; //! @brief map storing shared ptr of caches - std::unordered_map> _cache; + std::unordered_map>> _cache; }; } diff --git a/lib/Ray/sources/Window.cpp b/lib/Ray/sources/Window.cpp index 8a41d850..ec856fca 100644 --- a/lib/Ray/sources/Window.cpp +++ b/lib/Ray/sources/Window.cpp @@ -70,11 +70,21 @@ bool RAY::Window::isFocused(void) const return IsWindowFocused(); } -const RAY::Vector2 &RAY::Window::getDimensions(void) const +const RAY::Vector2 &RAY::Window::getDimensions(void) { + this->_dimensions.x = GetScreenWidth(); + this->_dimensions.y = GetScreenHeight(); return this->_dimensions; } +RAY::Window &RAY::Window::setDimensions(const Vector2 &dims) +{ + this->_dimensions = dims; + if (this->_isOpen) + SetWindowSize(dims.x, dims.y); + return *this; +} + void RAY::Window::setVisibleCursor(bool visible) { if (visible) @@ -184,4 +194,40 @@ bool RAY::Window::isReady() const void RAY::Window::setExitKey(RAY::Controller::Keyboard::Key key) { SetExitKey(key); +} + +unsigned RAY::Window::getConfigFlags(void) const +{ + return this->_flags; +} + +bool RAY::Window::isFullscreen(void) const +{ + return IsWindowFullscreen(); +} + +RAY::Window &RAY::Window::setConfigFlags(unsigned flags) +{ + if (this->_isOpen) + SetWindowState(flags); + this->_flags = flags; + return *this; +} + +RAY::Window &RAY::Window::toggleFullscreen() +{ + ToggleFullscreen(); + return *this; +} + +RAY::Window &RAY::Window::maximize() +{ + MaximizeWindow(); + return *this; +} + +RAY::Window &RAY::Window::restore() +{ + RestoreWindow(); + return *this; } \ No newline at end of file diff --git a/lib/Ray/sources/Window.hpp b/lib/Ray/sources/Window.hpp index 525f2992..b8370719 100644 --- a/lib/Ray/sources/Window.hpp +++ b/lib/Ray/sources/Window.hpp @@ -64,8 +64,11 @@ namespace RAY { //! @brief Check if window is currently focused bool isFocused(void) const; + //! @brief Get window dimensions + const RAY::Vector2 &getDimensions(void); + //! @brief Set window dimensions - const RAY::Vector2 &getDimensions(void) const; + RAY::Window &setDimensions(const Vector2 &dims); //! @brief Set the cursor visibility //! @param visible True if the cursor is visible @@ -136,6 +139,23 @@ namespace RAY { //! @info Calling this function override the previous closing key void setExitKey(Controller::Keyboard::Key key); + //! @return the configuration flgs for the window + unsigned getConfigFlags(void) const; + + //! @param flag the configuration flgs for the window + RAY::Window &setConfigFlags(unsigned flags); + + //! @brief set window to fullscreen + RAY::Window &toggleFullscreen(); + + //! @return true if the window is fullscreen + bool isFullscreen(void) const; + + //! @brief set window to max size + RAY::Window &maximize(); + + //! @brief reset window size + RAY::Window &restore(); private: //! @brief Creates window, and opens it if openNow is set to true diff --git a/sources/Component/Bomb/BasicBombComponent.cpp b/sources/Component/Bomb/BasicBombComponent.cpp index 97cbb70d..9de464d7 100644 --- a/sources/Component/Bomb/BasicBombComponent.cpp +++ b/sources/Component/Bomb/BasicBombComponent.cpp @@ -4,17 +4,19 @@ #include "BasicBombComponent.hpp" +#include + namespace BBM { - BasicBombComponent::BasicBombComponent(WAL::Entity &entity, int damage, int explosionRadius, unsigned ownerID) - : WAL::Component(entity), - damage(damage), - explosionRadius(explosionRadius), - ownerID(ownerID) + BasicBombComponent::BasicBombComponent(WAL::Entity &entity, int damage, int explosionRadius, std::vector ignored) + : WAL::Component(entity), + damage(damage), + explosionRadius(explosionRadius), + ignoredEntities(std::move(ignored)) {} WAL::Component *BasicBombComponent::clone(WAL::Entity &entity) const { - return new BasicBombComponent(entity, this->damage, this->explosionRadius, this->ownerID); + return new BasicBombComponent(entity, this->damage, this->explosionRadius, this->ignoredEntities); } } \ No newline at end of file diff --git a/sources/Component/Bomb/BasicBombComponent.hpp b/sources/Component/Bomb/BasicBombComponent.hpp index 1b9b46bf..5d3838c8 100644 --- a/sources/Component/Bomb/BasicBombComponent.hpp +++ b/sources/Component/Bomb/BasicBombComponent.hpp @@ -19,16 +19,14 @@ namespace BBM const int explosionRadius = 3; //! @brief The damage made by the explosion on an entity const int damage = 1; - //! @brief The ID of the owner. - unsigned ownerID; - //! @brief Should collisions with the owner be disabled.² - bool ignoreOwner = true; + //! @brief The list of IDs of ignored entities. + std::vector ignoredEntities; //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; //! @brief A component can't be instantiated, it should be derived. - explicit BasicBombComponent(WAL::Entity &entity, int damage, int explosionRadius, unsigned ownerID); + explicit BasicBombComponent(WAL::Entity &entity, int damage, int explosionRadius, std::vector ignored); //! @brief A component can't be instantiated, it should be derived. BasicBombComponent(const BasicBombComponent &) = default; diff --git a/sources/Component/Bonus/PlayerBonusComponent.hpp b/sources/Component/Bonus/PlayerBonusComponent.hpp index c6a10056..fadcc19d 100644 --- a/sources/Component/Bonus/PlayerBonusComponent.hpp +++ b/sources/Component/Bonus/PlayerBonusComponent.hpp @@ -15,15 +15,12 @@ namespace BBM class PlayerBonusComponent : public WAL::Component { public: - - //! @brief The number of seconds before a speed bonus expire. This variable is used to reset the nextSpeedBonusRate value. - std::chrono::nanoseconds speedBonusRate = 15s; - //! @brief The number of nanosecond before the expiration of a speed bonus. - std::chrono::nanoseconds nextSpeedBonusRate = speedBonusRate; - //! @brief The number of seconds before a range bonus expire. This variable is used to reset the nextRangeBonusRate value. - std::chrono::nanoseconds rangeBonusRate = 10s; - //! @brief The number of nanosecond before the expiration of a range bonus. - std::chrono::nanoseconds nextRangeBonusRate = rangeBonusRate; + //! @brief The number of seconds before a range bonus expire. This variable is used to reset the nextNoClipBonusRate value. + std::chrono::nanoseconds noClipBonusRate = 5s; + //! @brief The number of nanosecond before the expiration of a no clip bonus + std::chrono::nanoseconds nextNoClipRate = noClipBonusRate; + //! @brief To know if the player can clip through block + bool isNoClipOn = false; //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp index 652e6727..759e6d21 100644 --- a/sources/Component/Collision/CollisionComponent.cpp +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -54,4 +54,20 @@ namespace BBM bound({boundSize, boundSize, boundSize}), positionOffset({positionOffset, positionOffset, positionOffset}) {} + + CollisionComponent::CollidedAxis operator|(CollisionComponent::CollidedAxis first, + CollisionComponent::CollidedAxis second) + { + return static_cast(static_cast(first) | static_cast(second)); + } + + CollisionComponent::CollidedAxis &operator|=(CollisionComponent::CollidedAxis &self, + CollisionComponent::CollidedAxis other) + { + int &selfI = reinterpret_cast(self); + int otherI = static_cast(other); + + selfI |= otherI; + return reinterpret_cast(selfI); + } } \ No newline at end of file diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index e4244a7a..e50b4ead 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -17,9 +17,11 @@ namespace BBM //! @brief Used to tell the collided axis //! @note Usage: (collidedAxis (int given by callback)) & CollidedAxis::X enum CollidedAxis { + NONE = 0, X = 1, Y = 2, - Z = 4 + Z = 4, + ALL = 7 }; //! @brief onCollide functions to be called @@ -72,4 +74,7 @@ namespace BBM //! @brief A component can't be assigned CollisionComponent &operator=(const CollisionComponent &) = delete; }; + + CollisionComponent::CollidedAxis operator|(CollisionComponent::CollidedAxis first, CollisionComponent::CollidedAxis second); + CollisionComponent::CollidedAxis &operator|=(CollisionComponent::CollidedAxis &self, CollisionComponent::CollidedAxis other); } \ No newline at end of file diff --git a/sources/Component/Color/ColorComponent.cpp b/sources/Component/Color/ColorComponent.cpp new file mode 100644 index 00000000..994f7f10 --- /dev/null +++ b/sources/Component/Color/ColorComponent.cpp @@ -0,0 +1,24 @@ +// +// +// + +#include "ColorComponent.hpp" + +namespace BBM +{ + + ColorComponent::ColorComponent(WAL::Entity &entity, RAY::Color color) + : Component(entity), + color(color) + {} + + ColorComponent::ColorComponent(WAL::Entity &entity, unsigned char r, unsigned char g, unsigned char b, unsigned char a) + : Component(entity), + color(r, g, b, a) + {} + + WAL::Component *ColorComponent::clone(WAL::Entity &entity) const + { + return new ColorComponent(entity, this->color); + } +} // namespace WAL \ No newline at end of file diff --git a/sources/Component/Color/ColorComponent.hpp b/sources/Component/Color/ColorComponent.hpp new file mode 100644 index 00000000..d75b5818 --- /dev/null +++ b/sources/Component/Color/ColorComponent.hpp @@ -0,0 +1,33 @@ +// +// +// + +#pragma once + +#include "Color.hpp" +#include "Component/Component.hpp" + +namespace BBM +{ + //! @brief A basic color component + class ColorComponent : public WAL::Component + { + public: + //! @brief Get the editable color of this entity + RAY::Color color; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Create a new ColorComponent at a certain color + ColorComponent(WAL::Entity &entity, RAY::Color color); + //! @brief Create a new ColorComponent at a certain color + ColorComponent(WAL::Entity &entity, unsigned char r, unsigned char g, unsigned char b, unsigned char a); + //! @brief A color component is copy constructable + ColorComponent(const ColorComponent &) = default; + //! @brief A default destructor + ~ColorComponent() override = default; + //! @brief A color component is not assignable + ColorComponent &operator=(const ColorComponent &) = delete; + }; +} // namespace WAL \ No newline at end of file diff --git a/sources/Component/Controllable/ControllableComponent.hpp b/sources/Component/Controllable/ControllableComponent.hpp index 62c0bd13..f16de468 100644 --- a/sources/Component/Controllable/ControllableComponent.hpp +++ b/sources/Component/Controllable/ControllableComponent.hpp @@ -38,7 +38,7 @@ namespace BBM //! @brief input value for pause bool pause = false; //! @brief The speed applied to every controllable entities. - float speed = .25f; + float speed = .15f; //! @brief The layout used for this controllable. Layout layout = NONE; diff --git a/sources/Component/IAControllable/IAControllableComponent.cpp b/sources/Component/IAControllable/IAControllableComponent.cpp new file mode 100644 index 00000000..05f6eb9b --- /dev/null +++ b/sources/Component/IAControllable/IAControllableComponent.cpp @@ -0,0 +1,26 @@ +/* +** EPITECH PROJECT, 2021 +** Bomberman +** File description: +** IAControllableComponent +*/ + +#include +#include "Map/MapInfo.hpp" +#include "Component/IAControllable/IAControllableComponent.hpp" + +namespace BBM +{ + IAControllableComponent::IAControllableComponent(WAL::Entity &entity, std::string scriptPath) + : Component(entity), _scriptPath(scriptPath), _state() + { + if (std::filesystem::exists(scriptPath)) + _state.dofile(scriptPath); + } + + WAL::Component *IAControllableComponent::clone(WAL::Entity &entity) const + { + return new IAControllableComponent(entity, _scriptPath); + } + +} diff --git a/sources/Component/IAControllable/IAControllableComponent.hpp b/sources/Component/IAControllable/IAControllableComponent.hpp new file mode 100644 index 00000000..a1556662 --- /dev/null +++ b/sources/Component/IAControllable/IAControllableComponent.hpp @@ -0,0 +1,47 @@ +/* +** EPITECH PROJECT, 2021 +** Bomberman +** File description: +** IAComponent +*/ + +#ifndef IACOMPONENT_HPP_ +#define IACOMPONENT_HPP_ + +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" +#include "Models/Vector3.hpp" +#include "LuaGate.hpp" + +namespace BBM +{ + class IAControllableComponent : public WAL::Component + { + private: + //! @brief path to the lua script + const std::string _scriptPath; + public: + + //! @brief LuaGate state + LuaG::State _state; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Constructor + IAControllableComponent(WAL::Entity &entity, std::string scripPath); + + //! @brief A IA component can't be instantiated, it should be derived. + IAControllableComponent(const IAControllableComponent &) = default; + + //! @brief default destructor + ~IAControllableComponent() override = default; + + //! @brief A IA component can't be assigned + IAControllableComponent &operator=(const IAControllableComponent &) = delete; + protected: + }; +} + + +#endif /* !IACOMPONENT_HPP_ */ diff --git a/sources/Component/Renderer/Drawable2DComponent.hpp b/sources/Component/Renderer/Drawable2DComponent.hpp index 227eacd6..c6f86044 100644 --- a/sources/Component/Renderer/Drawable2DComponent.hpp +++ b/sources/Component/Renderer/Drawable2DComponent.hpp @@ -14,27 +14,40 @@ namespace BBM class Drawable2DComponent : public WAL::Component { public: + //! @brief Tells the renderer to draw in a particular order + bool drawBefore3D = false; + //! @brief The type of the component std::shared_ptr drawable; //! @brief ctor - Drawable2DComponent(WAL::Entity &entity, std::shared_ptr drawable) + Drawable2DComponent(WAL::Entity &entity, std::shared_ptr drawable, bool drawBefore3D = false) : WAL::Component(entity), - drawable(std::move(drawable)) + drawable(std::move(drawable)), + drawBefore3D(drawBefore3D) {} //! ctor template explicit Drawable2DComponent(WAL::Entity &entity, WAL::TypeHolder, Params &&...params) : WAL::Component(entity), - drawable(new T(std::forward(params)...)) + drawable(new T(std::forward(params)...)), + drawBefore3D(false) + {} + + //! ctor + template + explicit Drawable2DComponent(WAL::Entity &entity, WAL::TypeHolder, bool drawBefore3D, Params &&...params) + : WAL::Component(entity), + drawable(new T(std::forward(params)...)), + drawBefore3D(drawBefore3D) {} //! @brief Clone a component for another or the same entity. //! @param entity The entity that owns the ne component. WAL::Component *clone(WAL::Entity &entity) const override { - return new Drawable2DComponent(entity, this->drawable); + return new Drawable2DComponent(entity, this->drawable, this->drawBefore3D); } //! @brief Default copy ctor diff --git a/sources/Component/Score/ScoreComponent.cpp b/sources/Component/Score/ScoreComponent.cpp new file mode 100644 index 00000000..b54a835d --- /dev/null +++ b/sources/Component/Score/ScoreComponent.cpp @@ -0,0 +1,16 @@ + +#include "ScoreComponent.hpp" + +namespace BBM +{ + ScoreComponent::ScoreComponent(WAL::Entity &entity) + : Component(entity), + aliveTime(std::chrono::nanoseconds::zero()) + {} + + WAL::Component *ScoreComponent::clone(WAL::Entity &entity) const + { + return new ScoreComponent(entity); + } + +} // namespace WAL \ No newline at end of file diff --git a/sources/Component/Score/ScoreComponent.hpp b/sources/Component/Score/ScoreComponent.hpp new file mode 100644 index 00000000..15da0650 --- /dev/null +++ b/sources/Component/Score/ScoreComponent.hpp @@ -0,0 +1,28 @@ + +#pragma once + +#include "Component/Component.hpp" +#include + +namespace BBM +{ + //! @brief A basic position component + class ScoreComponent : public WAL::Component + { + public: + //! @brief the score of the player + std::chrono::nanoseconds aliveTime; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Create a new ScoreComponent linked to a specific entity + explicit ScoreComponent(WAL::Entity &entity); + //! @brief A position component is copy constructable + ScoreComponent(const ScoreComponent &) = default; + //! @brief A default destructor + ~ScoreComponent() override = default; + //! @brief A position component is not assignable + ScoreComponent &operator=(const ScoreComponent &) = delete; + }; +} // namespace WAL \ No newline at end of file diff --git a/sources/Component/Shaders/Items/BombExplosionShaderComponent.cpp b/sources/Component/Shaders/Items/BombExplosionShaderComponent.cpp new file mode 100644 index 00000000..c1ee13b6 --- /dev/null +++ b/sources/Component/Shaders/Items/BombExplosionShaderComponent.cpp @@ -0,0 +1,19 @@ +// +// Created by cbihan on 16/06/2021. +// + +#include "BombExplosionShaderComponent.hpp" + +namespace BBM +{ + + BombExplosionShaderComponent::BombExplosionShaderComponent(WAL::Entity &entity) : + Component(entity) + { + } + + WAL::Component *BombExplosionShaderComponent::clone(WAL::Entity &entity) const + { + return new BombExplosionShaderComponent(this->_entity); + } +} \ No newline at end of file diff --git a/sources/Component/Shaders/Items/BombExplosionShaderComponent.hpp b/sources/Component/Shaders/Items/BombExplosionShaderComponent.hpp new file mode 100644 index 00000000..99f214e7 --- /dev/null +++ b/sources/Component/Shaders/Items/BombExplosionShaderComponent.hpp @@ -0,0 +1,48 @@ +// +// Created by cbihan on 16/06/2021. +// + +#pragma once + +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" +#include + +using namespace std::chrono_literals; + +namespace BBM +{ + class BombExplosionShaderComponent : public WAL::Component + { + public: + //! @brief Explosion radius + float explosionRadius = 4; + //! @brief to have the shader move by the time + float frameCounter = 0; + //! @brief Transparency + float alpha = 1; + + //! @brief max explosion radius + static constexpr float maxRadius = 1.2; + + //! @brief The clock to use + std::chrono::nanoseconds clock = 0ns; + + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief ctor + explicit BombExplosionShaderComponent(WAL::Entity &entity); + + //! @brief Default copy ctor + BombExplosionShaderComponent(const BombExplosionShaderComponent &) = default; + + //! @brief Default dtor + ~BombExplosionShaderComponent() override = default; + + //! @brief Default assignment operator + BombExplosionShaderComponent &operator=(const BombExplosionShaderComponent &) = delete; + }; + +} diff --git a/sources/Component/Shaders/Items/WhiteShaderComponent.cpp b/sources/Component/Shaders/Items/WhiteShaderComponent.cpp new file mode 100644 index 00000000..638ffc91 --- /dev/null +++ b/sources/Component/Shaders/Items/WhiteShaderComponent.cpp @@ -0,0 +1,18 @@ +// +// Created by cbihan on 16/06/2021. +// + +#include "WhiteShaderComponent.hpp" + +namespace BBM +{ + WhiteShaderComponent::WhiteShaderComponent(WAL::Entity &entity) : + Component(entity) + { + } + + WAL::Component *WhiteShaderComponent::clone(WAL::Entity &entity) const + { + return new WhiteShaderComponent(this->_entity); + } +} \ No newline at end of file diff --git a/sources/Component/Shaders/Items/WhiteShaderComponent.hpp b/sources/Component/Shaders/Items/WhiteShaderComponent.hpp new file mode 100644 index 00000000..6c969818 --- /dev/null +++ b/sources/Component/Shaders/Items/WhiteShaderComponent.hpp @@ -0,0 +1,45 @@ +// +// Created by cbihan on 16/06/2021. +// + +#pragma once + + +#include "Component/Component.hpp" +#include + +using namespace std::chrono_literals; + +namespace BBM +{ + class WhiteShaderComponent : public WAL::Component + { + public: + //! @brief Transparency + float whiteValue = 0; + + //! @brief used to increase & decrease white value + float balance = 1; + + //! @brief The clock to use + std::chrono::nanoseconds clock = 0ns; + + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief ctor + explicit WhiteShaderComponent(WAL::Entity &entity); + + //! @brief Default copy ctor + WhiteShaderComponent(const WhiteShaderComponent &) = default; + + //! @brief Default dtor + ~WhiteShaderComponent() override = default; + + //! @brief Default assignment operator + WhiteShaderComponent &operator=(const WhiteShaderComponent &) = delete; + }; + +} + diff --git a/sources/Component/Shaders/ShaderComponent.cpp b/sources/Component/Shaders/ShaderComponent.cpp index 0320864e..e6f51917 100644 --- a/sources/Component/Shaders/ShaderComponent.cpp +++ b/sources/Component/Shaders/ShaderComponent.cpp @@ -16,29 +16,38 @@ namespace BBM RAY::Shader &ShaderComponent::getShader() { - return this->_shader; + return this->shader; } - ShaderComponent::ShaderComponent(WAL::Entity &entity, const std::string &fragmentFilePath, const std::string &vertexFilePath) + ShaderComponent::ShaderComponent(WAL::Entity &entity, + const std::string &fragmentFilePath, + const std::string &vertexFilePath, + const WAL::Callback &onFixedUpdate, + bool lonely) : WAL::Component(entity), - _shader(vertexFilePath, fragmentFilePath), - _fragmentFilePath(fragmentFilePath), - _vertexFilePath(vertexFilePath) + shader(vertexFilePath, fragmentFilePath, lonely), + fragmentFilePath(fragmentFilePath), + vertexFilePath(vertexFilePath), + update(onFixedUpdate) { } std::string ShaderComponent::getFragmentFilePath() const { - return this->_fragmentFilePath; + return this->fragmentFilePath; } std::string ShaderComponent::getVertexFilePath() const { - return this->_vertexFilePath; + return this->vertexFilePath; } - ShaderComponentModel::ShaderComponentModel(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) - : ShaderComponent(entity, std::move(fragmentFilePath), std::move(vertexFilePath)) + ShaderComponentModel::ShaderComponentModel(WAL::Entity &entity, + const std::string &fragmentFilePath, + const std::string &vertexFilePath, + const WAL::Callback &onFixedUpdate, + bool lonely) + : ShaderComponent(entity, fragmentFilePath, vertexFilePath, onFixedUpdate, lonely) { } @@ -50,8 +59,12 @@ namespace BBM throw std::runtime_error("No model available with a shader model component. This is unsupported."); } - ShaderComponentDrawable2D::ShaderComponentDrawable2D(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath) - : ShaderComponent(entity, std::move(fragmentFilePath), std::move(vertexFilePath)) + ShaderComponentDrawable2D::ShaderComponentDrawable2D(WAL::Entity &entity, + const std::string &fragmentFilePath, + const std::string &vertexFilePath, + const WAL::Callback &onFixedUpdate, + bool lonely) + : ShaderComponent(entity, fragmentFilePath, vertexFilePath, onFixedUpdate, lonely) { } } \ No newline at end of file diff --git a/sources/Component/Shaders/ShaderComponent.hpp b/sources/Component/Shaders/ShaderComponent.hpp index 51428de2..fe44a506 100644 --- a/sources/Component/Shaders/ShaderComponent.hpp +++ b/sources/Component/Shaders/ShaderComponent.hpp @@ -5,23 +5,29 @@ #pragma once #include +#include #include #include #include #include +#include +#include namespace BBM { class ShaderComponent : public WAL::Component { - private: - //! @brief The shader to be applied - RAY::Shader _shader; - //! @brief The path to the fragment file - std::string _fragmentFilePath; - //! @brief The path to the vertex file - std::string _vertexFilePath; public: + //! @brief The shader to be applied + RAY::Shader shader; + //! @brief The path to the fragment file + std::string fragmentFilePath; + //! @brief The path to the vertex file + std::string vertexFilePath; + + //! @brief the function called to update shaders vars + WAL::Callback update; + //! @brief getter for _shader RAY::Shader &getShader(); @@ -37,11 +43,18 @@ namespace BBM //! @brief ctor //! @note use empty string to omit a file - ShaderComponent(WAL::Entity &entity, const std::string& fragmentFilePath, const std::string& vertexFilePath = ""); + ShaderComponent(WAL::Entity &entity, + const std::string &fragmentFilePath, + const std::string &vertexFilePath = "", + const WAL::Callback &onFixedUpdate = WAL::Callback(), + bool lonely = false); + //! @brief Default copy ctor ShaderComponent(const ShaderComponent &) = default; + //! @brief Default dtor ~ShaderComponent() override = default; + //! @brief Default assignment operator ShaderComponent &operator=(const ShaderComponent &) = delete; }; @@ -55,11 +68,18 @@ namespace BBM //! @brief ctor //! @note use empty string to omit a file - ShaderComponentModel(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); + ShaderComponentModel(WAL::Entity &entity, + const std::string &fragmentFilePath, + const std::string &vertexFilePath = "", + const WAL::Callback &onFixedUpdate = WAL::Callback(), + bool lonely = false); + //! @brief Default copy ctor ShaderComponentModel(const ShaderComponentModel &) = default; + //! @brief Default dtor ~ShaderComponentModel() override = default; + //! @brief Default assignment operator ShaderComponentModel &operator=(const ShaderComponentModel &) = delete; }; @@ -69,11 +89,18 @@ namespace BBM public: //! @brief ctor //! @note use empty string to omit a file - ShaderComponentDrawable2D(WAL::Entity &entity, std::string fragmentFilePath, std::string vertexFilePath = ""); + ShaderComponentDrawable2D(WAL::Entity &entity, + const std::string &fragmentFilePath, + const std::string &vertexFilePath = "", + const WAL::Callback &onFixedUpdate = WAL::Callback(), + bool lonely = false); + //! @brief Default copy ctor ShaderComponentDrawable2D(const ShaderComponentDrawable2D &) = default; + //! @brief Default dtor ~ShaderComponentDrawable2D() override = default; + //! @brief Default assignment operator ShaderComponentDrawable2D &operator=(const ShaderComponentDrawable2D &) = delete; }; diff --git a/sources/Component/Stat/StatComponent.cpp b/sources/Component/Stat/StatComponent.cpp new file mode 100644 index 00000000..2e20f6f6 --- /dev/null +++ b/sources/Component/Stat/StatComponent.cpp @@ -0,0 +1,19 @@ +// +// +// + +#include "StatComponent.hpp" + +namespace BBM +{ + + StatComponent::StatComponent(WAL::Entity &entity, WAL::Callback callback) + : Component(entity), + updater(callback) + {} + + WAL::Component *StatComponent::clone(WAL::Entity &entity) const + { + return new StatComponent(entity, this->updater); + } +} // namespace WAL \ No newline at end of file diff --git a/sources/Component/Stat/StatComponent.hpp b/sources/Component/Stat/StatComponent.hpp new file mode 100644 index 00000000..75f9733f --- /dev/null +++ b/sources/Component/Stat/StatComponent.hpp @@ -0,0 +1,33 @@ +// +// +// + +#pragma once + +#include "Component/Component.hpp" +#include "Models/Callback.hpp" +#include "Wal.hpp" +#include "Component/Renderer/Drawable2DComponent.hpp" + +namespace BBM +{ + //! @brief A Stat component which contains a text and a callback + class StatComponent : public WAL::Component + { + public: + //! @brief onEvent callback + WAL::Callback updater; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Create a new StatComponent with a callback + StatComponent(WAL::Entity &entity, WAL::Callback callback); + //! @brief A color component is copy constructable + StatComponent(const StatComponent &) = default; + //! @brief A default destructor + ~StatComponent() override = default; + //! @brief A color component is not assignable + StatComponent &operator=(const StatComponent &) = delete; + }; +} // namespace WAL \ No newline at end of file diff --git a/sources/Component/Tag/TagComponent.hpp b/sources/Component/Tag/TagComponent.hpp index ff3d2466..9775c06d 100644 --- a/sources/Component/Tag/TagComponent.hpp +++ b/sources/Component/Tag/TagComponent.hpp @@ -54,6 +54,10 @@ namespace BBM constexpr const char Blowable[] = "Blowable"; // interact with visual features like camera constexpr const char Player[] = "Player"; + constexpr const char Unbreakable[] = "Unbreakable"; + constexpr const char Breakable[] = "Breakable"; + constexpr const char Hole[] = "Hole"; + constexpr const char Bumper[] = "Bumper"; // interact with bombs (getting damage etc) but doesn't stop explosion constexpr const char BlowablePass[] = "BlowablePass"; } diff --git a/sources/Items/Bonus.cpp b/sources/Items/Bonus.cpp index 47a5c2ba..e22aa658 100644 --- a/sources/Items/Bonus.cpp +++ b/sources/Items/Bonus.cpp @@ -7,50 +7,75 @@ #include #include "Component/Movable/MovableComponent.hpp" #include "Bonus.hpp" +#include +#include #include "Component/BombHolder/BombHolderComponent.hpp" namespace BBM { void Bonus::BombUpBonus(WAL::Entity &player, const WAL::Entity &bonus, CollisionComponent::CollidedAxis axis) { - if (bonus.shouldDelete() || axis != 7) + if (bonus.shouldDelete() || axis != CollisionComponent::CollidedAxis::ALL) return; auto *bombHolder = player.tryGetComponent(); if (!bombHolder) return; bombHolder->maxBombCount++; + const_cast(bonus).scheduleDeletion(); } void Bonus::ExplosionRangeBonus(WAL::Entity &player, const WAL::Entity &bonus, CollisionComponent::CollidedAxis axis) { - if (bonus.shouldDelete() || axis != 7) + if (bonus.shouldDelete() || axis != CollisionComponent::CollidedAxis::ALL) return; auto *bombHolder = player.tryGetComponent(); auto *playerBonus = player.tryGetComponent(); if (!bombHolder || !playerBonus) return; - if (bombHolder->explosionRadius <= 6) - bombHolder->explosionRadius++; - playerBonus->nextRangeBonusRate = playerBonus->rangeBonusRate; + bombHolder->explosionRadius++; + const_cast(bonus).scheduleDeletion(); } void Bonus::SpeedUpBonus(WAL::Entity &player, const WAL::Entity &bonus, CollisionComponent::CollidedAxis axis) { - if (bonus.shouldDelete() || axis != 7) + if (bonus.shouldDelete() || axis != CollisionComponent::CollidedAxis::ALL) return; auto *controllable = player.tryGetComponent(); auto *playerBonus = player.tryGetComponent(); if (!controllable || !playerBonus) return; - controllable->speed = 0.35f; - playerBonus->nextSpeedBonusRate = playerBonus->speedBonusRate; + controllable->speed += 0.025f; + const_cast(bonus).scheduleDeletion(); + } + + void Bonus::NoClipBonus(WAL::Entity &player, const WAL::Entity &bonus, CollisionComponent::CollidedAxis axis) + { + if (bonus.shouldDelete() || axis != CollisionComponent::CollidedAxis::ALL) + return; + auto *playerBonus = player.tryGetComponent(); + if (!playerBonus) + return; + playerBonus->nextNoClipRate = playerBonus->noClipBonusRate; + playerBonus->isNoClipOn = true; + const_cast(bonus).scheduleDeletion(); } Bonus::BonusType Bonus::getRandomBonusType() { - double rnd = static_cast(std::rand()) / RAND_MAX; + static std::default_random_engine generator(time(nullptr)); + std::map chanceValue = { + {NOTHING, 100.0f}, + {SPEEDUP, 45.0f}, + {BOMBSTOCK, 30.0f}, + {EXPLOSIONINC, 15.0f}, + {NOCLIP, 1.5f}, + }; + std::uniform_int_distribution distribution(1,1000); + float value = (distribution(generator) / 10); + BonusType bonus = NOTHING; - if (rnd < 0.8) - return (static_cast(std::rand() % (EXPLOSIONINC - 1) + 1)); - return (NOTHING); + for (auto &chance : chanceValue) + if (chance.second > value) + bonus = chance.first; + return (bonus); } } \ No newline at end of file diff --git a/sources/Items/Bonus.hpp b/sources/Items/Bonus.hpp index 6c15efd4..2284b63f 100644 --- a/sources/Items/Bonus.hpp +++ b/sources/Items/Bonus.hpp @@ -30,11 +30,17 @@ namespace BBM { //! @brief Apply bonus effect that allows to run faster static void SpeedUpBonus(WAL::Entity &player, const WAL::Entity &bonus, CollisionComponent::CollidedAxis axis); + //! @param bonus bonus + //! @param player the entity on which the effect will be applied + //! @brief Apply bonus effect that allows to pass trough breakbable walls + static void NoClipBonus(WAL::Entity &player, const WAL::Entity &bonus, CollisionComponent::CollidedAxis axis); + enum BonusType { NOTHING, BOMBSTOCK, SPEEDUP, - EXPLOSIONINC + EXPLOSIONINC, + NOCLIP }; static BonusType getRandomBonusType(); diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index 34e9ef83..520e3547 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "Component/Bonus/PlayerBonusComponent.hpp" #include namespace RAY3D = RAY::Drawables::Drawables3D; @@ -43,8 +44,8 @@ namespace BBM return; health->takeDmg(health->getHealthPoint()); } - - void MapGenerator::wallCollided(WAL::Entity &entity, + + void MapGenerator::wallCollision(WAL::Entity &entity, const WAL::Entity &wall, CollisionComponent::CollidedAxis collidedAxis) { @@ -60,6 +61,17 @@ namespace BBM mov->_velocity.z = 0; } + void MapGenerator::wallCollided(WAL::Entity &entity, + const WAL::Entity &wall, + CollisionComponent::CollidedAxis collidedAxis) + { + auto *playerBonus = entity.tryGetComponent(); + + if (playerBonus && playerBonus->isNoClipOn) + return; + wallCollision(entity, wall, collidedAxis); + } + void MapGenerator::wallDestroyed(WAL::Entity &entity, WAL::Wal &wal) { entity.scheduleDeletion(); @@ -67,10 +79,11 @@ namespace BBM static std::map map = { {Bonus::BonusType::BOMBSTOCK, "assets/items/bombup"}, {Bonus::BonusType::SPEEDUP, "assets/items/speedup"}, - {Bonus::BonusType::EXPLOSIONINC, "assets/items/fireup"} + {Bonus::BonusType::EXPLOSIONINC, "assets/items/fireup"}, + {Bonus::BonusType::NOCLIP, "assets/items/wallpass"} }; static std::vector> func = { - &Bonus::BombUpBonus, &Bonus::SpeedUpBonus, &Bonus::ExplosionRangeBonus + &Bonus::BombUpBonus, &Bonus::SpeedUpBonus, &Bonus::ExplosionRangeBonus, &Bonus::NoClipBonus }; auto bonusType = Bonus::getRandomBonusType(); @@ -86,9 +99,8 @@ namespace BBM entity.scheduleDeletion(); }) .addComponent(position.y) - .addComponent([](WAL::Entity &bonus, const WAL::Entity &player, CollisionComponent::CollidedAxis axis) { - bonus.scheduleDeletion(); - }, func[bonusType - 1], 0.5, .5) + .addComponent(WAL::Callback(), + func[bonusType - 1], 0.5, .5) .addComponent(5s, [](WAL::Entity &bonus, WAL::Wal &wal){ bonus.scheduleDeletion(); }) @@ -120,6 +132,7 @@ namespace BBM scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) .addComponent>() + .addComponent>() .addComponent( WAL::Callback(), &MapGenerator::wallCollided, 0.25, .75) @@ -156,7 +169,7 @@ namespace BBM .addComponent(Vector3f((width + 1) / 2, 0, -1)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollided, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75)) + &MapGenerator::wallCollision, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75)) .addComponent(unbreakableObj, false, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); @@ -164,7 +177,7 @@ namespace BBM .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollided, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75)) + &MapGenerator::wallCollision, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75)) .addComponent(unbreakableObj, false, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); @@ -172,7 +185,7 @@ namespace BBM .addComponent(Vector3f(width + 1, 0, height / 2)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollided, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1)) + &MapGenerator::wallCollision, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1)) .addComponent(unbreakableObj, false, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -180,7 +193,7 @@ namespace BBM .addComponent(Vector3f(-1, 0, height / 2)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollided, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1)) + &MapGenerator::wallCollision, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1)) .addComponent(unbreakableObj, false, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -227,6 +240,7 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) .addComponent>() + .addComponent>() .addComponent(1, &MapGenerator::wallDestroyed) .addComponent( WAL::Callback(), @@ -264,6 +278,7 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) .addComponent>() + .addComponent>() .addComponent( WAL::Callback(), &MapGenerator::wallCollided, 0.25, .75) @@ -281,6 +296,7 @@ namespace BBM WAL::Entity &holeEntity = scene->addEntity("Hole Block"); holeEntity.addComponent(Vector3f(coords.x, coords.y - 1, coords.z)) + .addComponent>() .addComponent( WAL::Callback(), &MapGenerator::holeCollide, Vector3f(0.25, 0.25, 0.25),Vector3f(0.75, 1.75, 0.75)); @@ -299,7 +315,8 @@ namespace BBM scene->addEntity("Bumper Block") .addComponent(Vector3f(coords.x, coords.y, coords.z)) - .addComponent(bumperObj, false,std::make_pair(MAP_DIFFUSE, bumperPng)) + .addComponent>() + .addComponent(bumperObj, false, std::make_pair(MAP_DIFFUSE, bumperPng)) .addComponent( WAL::Callback(), &MapGenerator::bumperCollide, Vector3f(0.25, 0.25, 0.25),Vector3f(0.75, 0.75, 0.75)); @@ -472,12 +489,12 @@ namespace BBM .addComponent(Vector3f(0, 0, 0)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25), Vector3f(width, 0.75, 0.75)); + &MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25), Vector3f(width + 1, 0.75, 0.75)); scene->addEntity("FloorUp Hitbox") .addComponent(Vector3f(0, 0, height)) .addComponent( WAL::Callback(), - &MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25),Vector3f(width, 0.75, 0.75)); + &MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25),Vector3f(width + 1, 0.75, 0.75)); } if (floor >= 2) scene->addEntity("Middle Hitbox") diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp index f7eef37c..ff7b712e 100644 --- a/sources/Map/Map.hpp +++ b/sources/Map/Map.hpp @@ -30,8 +30,7 @@ namespace BBM class MapGenerator { - private: - + public: //! @brief Enum of the block available. enum BlockType { @@ -45,6 +44,7 @@ namespace BBM UNBREAKABLE }; + private: using MapElem = std::function scene)>; using MapBlock = std::map, BlockType>; @@ -175,6 +175,10 @@ namespace BBM static const std::string secondFloorHolePath; public: + + static void wallCollision(WAL::Entity &entity, + const WAL::Entity &wall, + CollisionComponent::CollidedAxis collidedAxis); static void wallCollided(WAL::Entity &entity, const WAL::Entity &wall, CollisionComponent::CollidedAxis collidedAxis); diff --git a/sources/Map/MapInfo.cpp b/sources/Map/MapInfo.cpp new file mode 100644 index 00000000..f7c8f7c8 --- /dev/null +++ b/sources/Map/MapInfo.cpp @@ -0,0 +1,25 @@ +// +// Created by Louis Auzuret 09/06/21 +// + +#include "MapInfo.hpp" + +namespace BBM +{ + MapInfo::MapInfo(Vector3f pos, MapGenerator::BlockType type) + : x(pos.x), y(pos.y), z(pos.z), type(type) + { } + + MapInfo::MapInfo(const MapInfo &other) + : x(other.x), y(other.y), z(other.z), type(other.type) + { } + + MapInfo &MapInfo::operator=(MapInfo &other) + { + this->x = other.x; + this->y = other.y; + this->z = other.z; + this->type = other.type; + return *this; + } +} \ No newline at end of file diff --git a/sources/Map/MapInfo.hpp b/sources/Map/MapInfo.hpp new file mode 100644 index 00000000..78d10a83 --- /dev/null +++ b/sources/Map/MapInfo.hpp @@ -0,0 +1,37 @@ +// +// Created by Louis Auzuret on 09/06/21 +// + +#include "Map.hpp" + +namespace BBM +{ + class MapInfo + { + private: + public: + //! @brief Position on the x axis + float x; + + //! @brief Position on the y axis + float y; + + //! @brief Position on the z axis + float z; + + //! @brief Type of the block + int type; + + //! @brief Constructor + MapInfo(Vector3f pos, MapGenerator::BlockType type); + + //! @brief Default destructor + ~MapInfo() = default; + + //! @brief Default copy constructor + MapInfo(const MapInfo &); + + //! @brief Assignment operator + MapInfo &operator=(MapInfo &); + }; +} \ No newline at end of file diff --git a/sources/Models/GameState.hpp b/sources/Models/GameState.hpp index 4bb271b5..b3d506be 100644 --- a/sources/Models/GameState.hpp +++ b/sources/Models/GameState.hpp @@ -26,6 +26,8 @@ namespace BBM LobbyScene, TitleScreenScene, CreditScene, + HowToPlayScene, + ScoreScene, }; diff --git a/sources/Models/Vector3.hpp b/sources/Models/Vector3.hpp index 2af89bbc..3f6ef2cf 100644 --- a/sources/Models/Vector3.hpp +++ b/sources/Models/Vector3.hpp @@ -173,6 +173,21 @@ namespace BBM return Vector3(std::abs(this->x), std::abs(this->y), std::abs(this->z)); } + Vector3 trunc() const requires(std::is_floating_point_v) + { + return Vector3(std::trunc(this->x), std::trunc(this->y), std::trunc(this->z)); + } + + Vector3 ceil() const requires(std::is_floating_point_v) + { + return Vector3(std::ceil(this->x), std::ceil(this->y), std::ceil(this->z)); + } + + Vector3 floor() const requires(std::is_floating_point_v) + { + return Vector3(std::floor(this->x), std::floor(this->y), std::floor(this->z)); + } + Vector3 round() const requires(std::is_floating_point_v) { return Vector3(std::round(this->x), std::round(this->y), std::round(this->z)); diff --git a/sources/Runner/CreditScene.cpp b/sources/Runner/CreditScene.cpp index fa77c9ff..a0dfb539 100644 --- a/sources/Runner/CreditScene.cpp +++ b/sources/Runner/CreditScene.cpp @@ -23,7 +23,7 @@ namespace BBM {SoundComponent::JUMP, "assets/sounds/click.ogg"} }; - addMenuControl(*scene); + addMenuControl(*scene, sounds); scene->addEntity("background") .addComponent() .addComponent("assets/plain_menu_background.png"); diff --git a/sources/Runner/GameScene.cpp b/sources/Runner/GameScene.cpp index 51a0221f..c841644a 100644 --- a/sources/Runner/GameScene.cpp +++ b/sources/Runner/GameScene.cpp @@ -16,12 +16,19 @@ #include "Component/BombHolder/BombHolderComponent.hpp" #include "Component/Tag/TagComponent.hpp" #include "Component/Renderer/Drawable3DComponent.hpp" +#include "Component/Renderer/Drawable2DComponent.hpp" +#include +#include "Drawables/2D/Text.hpp" +#include "Drawables/Texture.hpp" #include "Component/Gravity/GravityComponent.hpp" #include "Component/BumperTimer/BumperTimerComponent.hpp" +#include "Component/Timer/TimerComponent.hpp" #include "Model/Model.hpp" #include "Map/Map.hpp" +#include "Component/Score/ScoreComponent.hpp" namespace RAY3D = RAY::Drawables::Drawables3D; +namespace RAY2D = RAY::Drawables::Drawables2D; namespace BBM { @@ -31,6 +38,15 @@ namespace BBM scene->addEntity("camera") .addComponent(8, 0, -5) .addComponent(Vector3f(8, 0, 8)); + scene->addEntity("Timer") + .addComponent(std::chrono::minutes (3), [](WAL::Entity &, WAL::Wal &) { + Runner::gameState.nextScene = GameState::ScoreScene; + }) + .addComponent(1920 / 2 - 2 * 30, 30, 0) + .addComponent("", 60, RAY::Vector2(), ORANGE); + scene->addEntity("background image") + .addComponent(true, "assets/background_game.png", false) + .addComponent(); MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16, hasHeights), scene); return scene; } @@ -48,10 +64,10 @@ namespace BBM .addComponent() .addComponent("assets/player/player.iqm", true) .addComponent() + .addComponent() .addComponent() .addComponent() .addComponent() - //.addComponent("assets/shaders/glsl330/predator.fs") .addComponent>() .addComponent>() .addComponent("assets/player/player.iqm", 3) diff --git a/sources/Runner/HowToPlayScene.cpp b/sources/Runner/HowToPlayScene.cpp new file mode 100644 index 00000000..782a70c0 --- /dev/null +++ b/sources/Runner/HowToPlayScene.cpp @@ -0,0 +1,81 @@ +#include +#include +#include "Runner.hpp" +#include +#include "Component/Music/MusicComponent.hpp" +#include "Component/Sound/SoundComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/Keyboard/KeyboardComponent.hpp" +#include "Component/Renderer/Drawable2DComponent.hpp" +#include "Component/Button/ButtonComponent.hpp" +#include "Drawables/2D/Text.hpp" + +namespace RAY2D = RAY::Drawables::Drawables2D; + +namespace BBM +{ + std::shared_ptr Runner::loadHowToPlayScene() + { + auto scene = std::make_shared(); + static const std::map sounds = { + {SoundComponent::JUMP, "assets/sounds/click.ogg"} + }; + + addMenuControl(*scene, sounds); + scene->addEntity("Control entity") + .addComponent("assets/musics/music_player_select.ogg") + .addComponent(sounds); + scene->addEntity("background") + .addComponent() + .addComponent("assets/plain_menu_background.png"); + scene->addEntity("scene title text") + .addComponent(1920 / 3, 100, 0) + .addComponent("How To Play?", 120, RAY::Vector2(), ORANGE); + + scene->addEntity("select text") + .addComponent(1920 / 8, 1080 / 3, 0) + .addComponent("Select:", 60, RAY::Vector2(), ORANGE); + scene->addEntity("select") + .addComponent(1920 / 7, 1080 / 2.5, 0) + .addComponent("Space/A Button", 35, RAY::Vector2(), BLACK); + scene->addEntity("change skin text") + .addComponent(1920 / 8, 1080 / 2, 0) + .addComponent("Change Skin/Drop Bomb:", 60, RAY::Vector2(), ORANGE); + scene->addEntity("change skin") + .addComponent(1920 / 7, 1080 / 1.75, 0) + .addComponent("E/B Button", 35, RAY::Vector2(), BLACK); + scene->addEntity("move text") + .addComponent(1920 / 1.75, 1080 / 3, 0) + .addComponent("Move:", 60, RAY::Vector2(), ORANGE); + scene->addEntity("move") + .addComponent(1920 / 1.75, 1080 / 2.5, 0) + .addComponent("Q-Z-S-D/Arrow/Joystick", 35, RAY::Vector2(), BLACK); + scene->addEntity("back text") + .addComponent(1920 / 1.75, 1080 / 2, 0) + .addComponent("Back/Pause:", 60, RAY::Vector2(), ORANGE); + scene->addEntity("back") + .addComponent(1920 / 1.75, 1080 / 1.75, 0) + .addComponent("Esc / Controller's Home button:", 35, RAY::Vector2(), BLACK); + auto &back = scene->addEntity("back to menu") + .addComponent(10, 1080 - 85, 0) + .addComponent("assets/buttons/button_back.png") + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + gameState.nextScene = BBM::GameState::SceneID::LobbyScene; + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); + + texture->use("assets/buttons/button_back.png"); + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); + + texture->use("assets/buttons/button_back_hovered.png"); + }); + return scene; + } +} \ No newline at end of file diff --git a/sources/Runner/LobbyScene.cpp b/sources/Runner/LobbyScene.cpp index efdd90a3..6c0f6f3a 100644 --- a/sources/Runner/LobbyScene.cpp +++ b/sources/Runner/LobbyScene.cpp @@ -33,7 +33,7 @@ namespace BBM }; auto scene = std::make_shared(); - addMenuControl(*scene); + addMenuControl(*scene, sounds); scene->addEntity("Control entity") .addComponent("assets/musics/music_player_select.ogg") .addComponent(sounds); @@ -59,39 +59,55 @@ namespace BBM .addComponent([](WAL::Entity &entity, WAL::Wal &wal) { if (Runner::gameState.currentScene != GameState::LobbyScene - || !LobbySystem::playersAreReady(*wal.getScene())) + || !LobbySystem::playersAreReady(*wal.getScene())) return; LobbySystem::switchToGame(wal); }) .addComponent>(); - - auto &back = scene->addEntity("back to menu") .addComponent(10, 1080 - 85, 0) .addComponent("assets/buttons/button_back.png") - .addComponent([](WAL::Entity &entity, WAL::Wal &wal) + .addComponent([](WAL::Entity &entity, WAL::Wal &) { gameState.nextScene = BBM::GameState::SceneID::MainMenuScene; - wal.getSystem().unloadLobby(); }) .addComponent([](WAL::Entity &entity, WAL::Wal &) { - auto *texture = dynamic_cast(entity.getComponent().drawable.get()); + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); - texture->use("assets/buttons/button_back.png"); + texture->use("assets/buttons/button_back.png"); }) .addComponent([](WAL::Entity &entity, WAL::Wal &) { - auto *texture = dynamic_cast(entity.getComponent().drawable.get()); + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); texture->use("assets/buttons/button_back_hovered.png"); }); + auto &howToPlay = scene->addEntity("to to play") + .addComponent(1920 - 10 - 75, 1080 - 85, 0) + .addComponent("assets/buttons/button_htp.png") + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + gameState.nextScene = BBM::GameState::SceneID::HowToPlayScene; + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); + + texture->use("assets/buttons/button_htp.png"); + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); + + texture->use("assets/buttons/button_htp_hovered.png"); + }); auto &lavaOption = scene->addEntity("lava option text") .addComponent(1920 / 6, 1.85 * 1080 / 3, 0) .addComponent("Lava: Off", 70, RAY::Vector2(), BLACK) .addComponent([](WAL::Entity &entity, WAL::Wal &wal) { - auto *text = dynamic_cast(entity.getComponent().drawable.get()); + RAY2D::Text *text = dynamic_cast(entity.getComponent().drawable.get()); if (text->getString().find("Off") != std::string::npos) { text->setText("Lava: On"); @@ -179,13 +195,15 @@ namespace BBM .addComponent("assets/player/icons/none.png"); auto &ready = scene->addEntity("ready") .addComponent(224 * (i + 1) + 200 * i, 1080 / 3, 0) + // todo check why it does this | hacky way to fix ready texture .addComponent(); player.addComponent(i, ready, playerTile); } scene->addEntity("camera") .addComponent(-5, 0, -5) .addComponent(Vector3f(8, 0, 8)); - play.getComponent().setButtonLinks(&heightOption, &back, &back, nullptr); + play.getComponent().setButtonLinks(&lavaOption, &back, &back, &howToPlay); + howToPlay.getComponent().setButtonLinks(&play, nullptr, &play); back.getComponent().setButtonLinks(&play, nullptr, nullptr, &play); lavaOption.getComponent().setButtonLinks(nullptr, &heightOption, nullptr, &aiMore); heightOption.getComponent().setButtonLinks(&lavaOption, &play, nullptr, &aiLess); diff --git a/sources/Runner/MainMenuScene.cpp b/sources/Runner/MainMenuScene.cpp index 42067222..33377954 100644 --- a/sources/Runner/MainMenuScene.cpp +++ b/sources/Runner/MainMenuScene.cpp @@ -23,7 +23,7 @@ namespace BBM }; auto scene = std::make_shared(); - addMenuControl(*scene); + addMenuControl(*scene, sounds); scene->addEntity("Control entity") .addComponent("assets/musics/music_title.ogg") .addComponent(sounds); diff --git a/sources/Runner/PauseMenuScene.cpp b/sources/Runner/PauseMenuScene.cpp index cf7d66c6..3154e360 100644 --- a/sources/Runner/PauseMenuScene.cpp +++ b/sources/Runner/PauseMenuScene.cpp @@ -23,7 +23,7 @@ namespace BBM }; auto scene = std::make_shared(); - addMenuControl(*scene); + addMenuControl(*scene, sounds); scene->addEntity("Control entity") .addComponent("assets/musics/music_player_select.ogg") .addComponent(sounds); diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 2e29e4b2..98507d1f 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -12,10 +12,19 @@ #include "System/Controllable/ControllableSystem.hpp" #include "System/Gamepad/GamepadSystem.hpp" #include +#include "Component/Button/ButtonComponent.hpp" +#include +#include +#include +#include +#include +#include "Component/Renderer/CameraComponent.hpp" +#include "Component/Renderer/Drawable3DComponent.hpp" #include "Component/Renderer/Drawable2DComponent.hpp" #include "Runner.hpp" #include "Models/GameState.hpp" #include +#include #include #include #include @@ -24,8 +33,12 @@ #include #include #include +#include "System/Shaders/ShaderSystem.hpp" +#include "System/Shaders/ShaderDrawable2DSystem.hpp" +#include "System/Shaders/ShaderModelSystem.hpp" #include "System/Animation/AnimationsSystem.hpp" #include "Map/Map.hpp" +#include "System/IAControllable/IAControllableSystem.hpp" #include "System/MenuControllable/MenuControllableSystem.hpp" #include #include "System/Sound/PlayerSoundManagerSystem.hpp" @@ -34,7 +47,10 @@ #include "System/BumperTimer/BumperTimerSystem.hpp" #include "System/Music/MusicSystem.hpp" #include "System/Lobby/LobbySystem.hpp" +#include "System/Score/ScoreSystem.hpp" +#include "System/EndCondition/EndConditionSystem.hpp" #include "Component/Lobby/LobbyComponent.hpp" +#include "System/Bonus/BonusUISystem.hpp" namespace BBM { @@ -46,19 +62,18 @@ namespace BBM auto &view = engine.getScene()->view(); if (RAY::Window::getInstance().shouldClose()) engine.shouldClose = true; - if (gameState.currentScene == GameState::SceneID::GameScene || gameState.currentScene == GameState::SceneID::SplashScreen) { + if (gameState.currentScene == GameState::SceneID::GameScene) { for (auto &[_, component]: engine.getScene()->view()) { if (component.pause && gameState.currentScene == GameState::SceneID::GameScene) { gameState.nextScene = GameState::SceneID::PauseMenuScene; break; - } else if (gameState.currentScene == GameState::SceneID::SplashScreen && component.select) { - gameState.nextScene = GameState::SceneID::TitleScreenScene; - break; } } } if (gameState.nextScene == gameState.currentScene) return; + if (gameState.nextScene == GameState::SceneID::ScoreScene) + gameState._loadedScenes[GameState::SceneID::ScoreScene] = Runner::loadScoreScene(*engine.getScene()); gameState._loadedScenes[gameState.currentScene] = engine.getScene(); engine.changeScene(gameState._loadedScenes[gameState.nextScene]); gameState.currentScene = gameState.nextScene; @@ -67,14 +82,17 @@ namespace BBM void Runner::addSystems(WAL::Wal &wal) { wal.addSystem() + .addSystem() .addSystem() .addSystem() + .addSystem() .addSystem() .addSystem() .addSystem() .addSystem() .addSystem() .addSystem() + .addSystem() .addSystem() .addSystem() .addSystem() @@ -85,29 +103,37 @@ namespace BBM .addSystem() .addSystem() .addSystem() + .addSystem() + .addSystem() + .addSystem() + .addSystem() + .addSystem() .addSystem(); } void Runner::enableRaylib(WAL::Wal &wal) { RAY::TraceLog::setLevel(LOG_WARNING); - RAY::Window &window = RAY::Window::getInstance(1920, 1080, "Bomberman"); + RAY::Window &window = RAY::Window::getInstance(1280, 720, "Bomberman", FLAG_WINDOW_RESIZABLE); wal.addSystem() .addSystem() .addSystem(window); } - void Runner::addMenuControl(WAL::Scene &scene) + void Runner::addMenuControl(WAL::Scene &scene, const std::map &sounds) { scene.addEntity("Keyboard default control") .addComponent() + .addComponent(sounds) .addComponent(); scene.addEntity("Keyboard second control") .addComponent() + .addComponent(sounds) .addComponent(ControllableComponent::Layout::KEYBOARD_1); for (int i = 0; i < 4; i++) { scene.addEntity("Gamepad controller") .addComponent() + .addComponent(sounds) .addComponent(i); } } @@ -121,6 +147,7 @@ namespace BBM gameState._loadedScenes[GameState::SceneID::CreditScene] = loadCreditScene(); gameState._loadedScenes[GameState::SceneID::SplashScreen] = loadSplashScreenScene(); gameState._loadedScenes[GameState::SceneID::LobbyScene] = loadLobbyScene(); + gameState._loadedScenes[GameState::SceneID::HowToPlayScene] = loadHowToPlayScene(); } int Runner::run() @@ -131,13 +158,7 @@ namespace BBM Runner::enableRaylib(wal); Runner::loadScenes(); wal.changeScene(Runner::gameState._loadedScenes[GameState::SceneID::SplashScreen]); - - try { - wal.run(Runner::updateState, Runner::gameState); - return 0; - } catch (const std::exception &ex) { - std::cerr << ex.what() << std::endl; - return 1; - } + wal.run(Runner::updateState, Runner::gameState); + return 0; } } \ No newline at end of file diff --git a/sources/Runner/Runner.hpp b/sources/Runner/Runner.hpp index b5b0bb4d..3c1d9d04 100644 --- a/sources/Runner/Runner.hpp +++ b/sources/Runner/Runner.hpp @@ -5,6 +5,8 @@ #pragma once #include "Models/GameState.hpp" #include "Wal.hpp" +#include +#include "Component/Sound/SoundComponent.hpp" namespace BBM { @@ -30,7 +32,7 @@ namespace BBM //! @brief init all raylib-related data & context static void enableRaylib(WAL::Wal &wal); - static void addMenuControl(WAL::Scene &scene); + static void addMenuControl(WAL::Scene &scene, const std::map &sounds = {}); //! @brief load all data related to title screen static std::shared_ptr loadTitleScreenScene(); @@ -61,6 +63,13 @@ namespace BBM //! @brief load all data related to splash screen static std::shared_ptr loadSplashScreenScene(); + //! @brief load how to play screen + static std::shared_ptr loadHowToPlayScene(); + //! @brief load all data related to score scene screen + //! @param gameScene scene containing players (to know the scores) + static std::shared_ptr loadScoreScene(WAL::Scene &gameScene); + + //! @brief loads all scenes in the game state static void loadScenes(); }; diff --git a/sources/Runner/ScoreScene.cpp b/sources/Runner/ScoreScene.cpp new file mode 100644 index 00000000..4f80babb --- /dev/null +++ b/sources/Runner/ScoreScene.cpp @@ -0,0 +1,93 @@ + +#include +#include "Runner.hpp" +#include +#include "Component/Button/ButtonComponent.hpp" +#include "Component/Music/MusicComponent.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/Renderer/Drawable2DComponent.hpp" +#include "Component/Renderer/Drawable3DComponent.hpp" +#include "Component/Sound/SoundComponent.hpp" +#include "Drawables/Texture.hpp" +#include "Drawables/2D/Text.hpp" +#include "Component/Score/ScoreComponent.hpp" +#include "Model/Model.hpp" + +namespace RAY2D = RAY::Drawables::Drawables2D; +namespace RAY3D = RAY::Drawables::Drawables3D; + +namespace BBM +{ + std::shared_ptr Runner::loadScoreScene(WAL::Scene &gameScene) + { + auto scene = std::make_shared(); + std::vector playersIconPath; + std::vector> players; + static const std::map sounds = { + {SoundComponent::JUMP, "assets/sounds/click.ogg"} + }; + static const std::vector tilesColor = { + GOLD, GRAY, BROWN, PURPLE + }; + static const std::vector rankName = { + "1st", "2nd", "3rd", "4th" + }; + + for (auto &[entity, score, drawable]: gameScene.view()) + players.push_back(entity); + std::sort(players.begin(), players.end(), [](WAL::Entity &entityA, WAL::Entity &entityB) { + return entityA.getComponent().aliveTime > entityB.getComponent().aliveTime; + }); + + for (auto &entity: players) { + RAY3D::Model *model = dynamic_cast(entity.get().getComponent().drawable.get()); + std::string path = model->getTextureByMaterial(MAP_DIFFUSE).getResourcePath(); + playersIconPath.push_back(path.replace(path.find("textures"), std::string("textures").size(), "icons")); + } + + addMenuControl(*scene, sounds); + scene->addEntity("Audio ressources") + .addComponent("assets/musics/music_result.ogg") + .addComponent(sounds); + scene->addEntity("background") + .addComponent() + .addComponent("assets/plain_menu_background.png"); + scene->addEntity("scene title text") + .addComponent(1920 / 3.25, 100, 0) + .addComponent("GAME OVER", 120, RAY::Vector2(), ORANGE); + scene->addEntity("scene title text") + .addComponent(1920 / 2.37, 250, 0) + .addComponent("CONGRATS", 50, RAY::Vector2(), ORANGE); + for (int i = 0; i < players.size(); i++) { + auto &playerTile = scene->addEntity("player tile") + .addComponent(224 * (i + 1) + 200 * i, 1080 / 2.5, 0) + .addComponent(RAY::Vector2(224 * (i + 1) + 200 * i, 1080 / 3), + RAY::Vector2(200, 200), tilesColor[i]); + auto &playerRank = scene->addEntity("player rank name") + .addComponent(224 * (i + 1) + 200 * i, 1080 / 2.75, 0) + .addComponent(rankName[i], 30, + RAY::Vector2(224 * (i + 1) + 200 * i, 1080 / 3), + tilesColor[i]); + auto &player = scene->addEntity("player") + .addComponent(224 * (i + 1) + 200 * i, 1080 / 2.5, 0) + .addComponent(playersIconPath[i]); + } + scene->addEntity("back to main menu") + .addComponent(10, 1080 - 85, 0) + .addComponent("assets/buttons/button_back.png") + .addComponent([](WAL::Entity &entity, WAL::Wal &) { + gameState.nextScene = BBM::GameState::SceneID::MainMenuScene; + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) { + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); + + texture->use("assets/buttons/button_back.png"); + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) { + RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); + + texture->use("assets/buttons/button_back_hovered.png"); + }); + return scene; + } +} \ No newline at end of file diff --git a/sources/Runner/SettingsMenuScene.cpp b/sources/Runner/SettingsMenuScene.cpp index 8883bbeb..1fd24c48 100644 --- a/sources/Runner/SettingsMenuScene.cpp +++ b/sources/Runner/SettingsMenuScene.cpp @@ -24,7 +24,7 @@ namespace BBM {SoundComponent::JUMP, "assets/sounds/click.ogg"} }; - addMenuControl(*scene); + addMenuControl(*scene, sounds); scene->addEntity("Control entity") .addComponent("assets/musics/music_title.ogg") .addComponent(sounds); @@ -35,7 +35,7 @@ namespace BBM .addComponent(1920 / 3, 180, 0) .addComponent("assets/logo_small.png"); auto &music = scene->addEntity("music text") - .addComponent(1920 / 2.5, 1080 - 540, 0) + .addComponent(1920 / 2.5, 1080 - 100 - 540, 0) .addComponent("Music Volume", 70, RAY::Vector2(), BLACK) .addComponent() .addComponent([](WAL::Entity &entity, WAL::Wal &) @@ -48,7 +48,7 @@ namespace BBM }); auto &musicUp = scene->addEntity("music up button") - .addComponent(1920 / 1.5, 1080 - 540, 0) + .addComponent(1920 / 1.5, 1080 - 100 - 540, 0) .addComponent("assets/buttons/button_plus.png") .addComponent("assets/musics/music_title.ogg") .addComponent([](WAL::Entity &entity, WAL::Wal &) @@ -71,7 +71,7 @@ namespace BBM }); auto &musicDown = scene->addEntity("music down button") - .addComponent(1920 / 3, 1080 - 540, 0) + .addComponent(1920 / 3, 1080 - 100 - 540, 0) .addComponent("assets/buttons/button_minus.png") .addComponent("assets/musics/music_title.ogg") .addComponent([](WAL::Entity &entity, WAL::Wal &) @@ -94,7 +94,7 @@ namespace BBM }); auto &sound = scene->addEntity("sound text") - .addComponent(1920 / 2.5, 1080 - 360, 0) + .addComponent(1920 / 2.5, 1080 - 100 - 360, 0) .addComponent("Sound Volume", 70, RAY::Vector2(), BLACK) .addComponent() .addComponent([](WAL::Entity &entity, WAL::Wal &) @@ -107,9 +107,10 @@ namespace BBM }); auto &soundUp = scene->addEntity("sound up button") - .addComponent(1920 / 1.5, 1080 - 360, 0) + .addComponent(1920 / 1.5, 1080 - 100 - 360, 0) .addComponent("assets/buttons/button_plus.png") .addComponent(sounds) + .addComponent() .addComponent([](WAL::Entity &entity, WAL::Wal &) { auto &component = entity.getComponent(); @@ -130,9 +131,10 @@ namespace BBM }); auto &soundDown = scene->addEntity("sound down button") - .addComponent(1920 / 3, 1080 - 360, 0) + .addComponent(1920 / 3, 1080 - 100 - 360, 0) .addComponent("assets/buttons/button_minus.png") .addComponent(sounds) + .addComponent() .addComponent([](WAL::Entity &entity, WAL::Wal &) { RAY::Texture *texture = dynamic_cast(entity.getComponent().drawable.get()); @@ -153,7 +155,7 @@ namespace BBM }); auto &debug = scene->addEntity("debug text") - .addComponent(1920 / 2.5, 1080 - 180, 0) + .addComponent(1920 / 2.5, 1080 - 100 - 180, 0) .addComponent("Debug Mode: Off", 70, RAY::Vector2(), BLACK) .addComponent([](WAL::Entity &entity, WAL::Wal &wal) { @@ -175,6 +177,31 @@ namespace BBM { entity.getComponent().drawable->setColor(ORANGE); }); + auto &fullscreen = scene->addEntity("fullscreen text") + .addComponent(1920 / 2.5, 1080 - 100 - 50, 0) + .addComponent("Fullscreen: Off", 70, RAY::Vector2(), BLACK) + .addComponent([](WAL::Entity &entity, WAL::Wal &wal) + { + RAY2D::Text *text = dynamic_cast(entity.getComponent().drawable.get()); + RAY::Window &window = RAY::Window::getInstance(); + + if (text->getString().find("Off") != std::string::npos) { + text->setText("Fullscreen: On"); + window.setDimensions(RAY::Vector2(1920, 1080)); + } else { + text->setText("Fullscreen: Off"); + window.setDimensions(RAY::Vector2(1280, 720)); + } + window.toggleFullscreen(); + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + entity.getComponent().drawable->setColor(BLACK); + }) + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + entity.getComponent().drawable->setColor(ORANGE); + }); auto &back = scene->addEntity("back to menu") .addComponent(10, 1080 - 85, 0) .addComponent("assets/buttons/button_back.png") @@ -204,8 +231,9 @@ namespace BBM sound.getComponent().setButtonLinks(&music, &debug, &soundDown, &soundUp); soundDown.getComponent().setButtonLinks(&music, &debug, nullptr, &sound); soundUp.getComponent().setButtonLinks(&music, &debug, &sound); - debug.getComponent().setButtonLinks(&sound, &back, &back); - back.getComponent().setButtonLinks(&debug, nullptr, nullptr, &debug); + debug.getComponent().setButtonLinks(&sound, &fullscreen); + fullscreen.getComponent().setButtonLinks(&debug, &back, &back); + back.getComponent().setButtonLinks(&fullscreen, nullptr, nullptr, &fullscreen); return scene; } } \ No newline at end of file diff --git a/sources/Runner/SplashScreenScene.cpp b/sources/Runner/SplashScreenScene.cpp index a22d20da..3d0cc1ae 100644 --- a/sources/Runner/SplashScreenScene.cpp +++ b/sources/Runner/SplashScreenScene.cpp @@ -30,7 +30,13 @@ namespace BBM .addComponent("powered by", 30, RAY::Vector2(), BLACK); auto &skipText = scene->addEntity("Press space to skip") .addComponent(1920 - 250, 1080 - 30, 0) - .addComponent("Press space to skip", 20, RAY::Vector2(), BLACK); + .addComponent("Press space to skip", 20, RAY::Vector2(), BLACK) + .addComponent() + .addComponent() + .addComponent([](WAL::Entity &entity, WAL::Wal &) + { + gameState.nextScene = BBM::GameState::SceneID::TitleScreenScene; + }); return scene; } } \ No newline at end of file diff --git a/sources/Runner/TitleScreenScene.cpp b/sources/Runner/TitleScreenScene.cpp index 729434f3..defa265e 100644 --- a/sources/Runner/TitleScreenScene.cpp +++ b/sources/Runner/TitleScreenScene.cpp @@ -22,7 +22,7 @@ namespace BBM {SoundComponent::JUMP, "assets/sounds/click.ogg"} }; auto scene = std::make_shared(); - addMenuControl(*scene); + addMenuControl(*scene, sounds); scene->addEntity("control") .addComponent(sounds) .addComponent("assets/musics/music_title.ogg"); diff --git a/sources/System/Bomb/BombSystem.cpp b/sources/System/Bomb/BombSystem.cpp index 6049c874..39b7698b 100644 --- a/sources/System/Bomb/BombSystem.cpp +++ b/sources/System/Bomb/BombSystem.cpp @@ -14,15 +14,16 @@ namespace BBM void BombSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) { auto &bomb = entity.get(); - if (!bomb.ignoreOwner) + + if (bomb.ignoredEntities.empty()) return; + auto &pos = entity.get(); for (auto &[owner, ownerPos, _] : this->_wal.getScene()->view()) { - if (owner.getUid() != bomb.ownerID) - continue; - if (pos.position != ownerPos.position.round()) { - bomb.ignoreOwner = false; - return; + if (pos.position.distance(ownerPos.position) >= 1.1) { + bomb.ignoredEntities.erase( + std::remove(bomb.ignoredEntities.begin(), bomb.ignoredEntities.end(), owner.getUid()), + bomb.ignoredEntities.end()); } } } diff --git a/sources/System/BombHolder/BombHolderSystem.cpp b/sources/System/BombHolder/BombHolderSystem.cpp index d67f16c7..02ed40aa 100644 --- a/sources/System/BombHolder/BombHolderSystem.cpp +++ b/sources/System/BombHolder/BombHolderSystem.cpp @@ -2,7 +2,6 @@ // Created by Zoe Roux on 5/31/21. // -#include #include #include "Component/Timer/TimerComponent.hpp" #include "System/Event/EventSystem.hpp" @@ -11,8 +10,13 @@ #include "Component/Health/HealthComponent.hpp" #include #include +#include +#include "Component/Shaders/Items/BombExplosionShaderComponent.hpp" +#include +#include "Component/Shaders/ShaderComponent.hpp" #include "Component/Collision/CollisionComponent.hpp" #include "Component/Tag/TagComponent.hpp" +#include "Component/Shaders/Items/WhiteShaderComponent.hpp" using namespace std::chrono_literals; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -26,7 +30,8 @@ namespace BBM CollisionComponent::CollidedAxis collidedAxis) { auto &bombInfo = bomb.getComponent(); - if (bombInfo.ignoreOwner && bombInfo.ownerID == entity.getUid()) + auto found = std::find(bombInfo.ignoredEntities.begin(), bombInfo.ignoredEntities.end(), entity.getUid()); + if (found != bombInfo.ignoredEntities.end()) return; return MapGenerator::wallCollided(entity, bomb, collidedAxis); } @@ -44,10 +49,31 @@ namespace BBM return; wal.getScene()->scheduleNewEntity("explosion") .addComponent(position) + .addComponent() + .addComponent("assets/shaders/explosion.fs", "assets/shaders/explosion.vs", [](WAL::Entity &entity, WAL::Wal &wal, std::chrono::nanoseconds dtime) { + auto &ctx = entity.getComponent(); + auto &shader = entity.getComponent(); + + ctx.clock += dtime; + if (duration_cast(ctx.clock).count() <= 10) + return; + ctx.clock = 0ns; + ctx.explosionRadius -= 0.6; + if (ctx.explosionRadius < BombExplosionShaderComponent::maxRadius) { + ctx.explosionRadius = BombExplosionShaderComponent::maxRadius; + ctx.alpha -= 0.1; + // slow the explosion movement + ctx.frameCounter -= 0.1; + } + ctx.frameCounter += 0.2; + shader.shader.setShaderUniformVar("frame", ctx.frameCounter); + shader.shader.setShaderUniformVar("alpha", ctx.alpha); + shader.shader.setShaderUniformVar("radius", ctx.explosionRadius); + }) .addComponent(500ms, [](WAL::Entity &explosion, WAL::Wal &wal) { explosion.scheduleDeletion(); }) - .addComponent("assets/bombs/explosion/explosion.glb", false, + .addComponent(RAY::Mesh::MeshSphere(0.5, 16, 16), std::make_pair( MAP_DIFFUSE, "assets/bombs/explosion/blast.png" @@ -89,10 +115,17 @@ namespace BBM _dispatchExplosion(position, wal, explosionRadius); } - void BombHolderSystem::_spawnBomb(Vector3f position, BombHolderComponent &holder, unsigned id) + void BombHolderSystem::_spawnBomb(Vector3f position, BombHolderComponent &holder) { + std::vector overlapping; + + for (auto &[entity, pos, _] : this->_wal.getScene()->view()) { + if (position.distance(pos.position) <= 1.1) + overlapping.emplace_back(entity.getUid()); + } + this->_wal.getScene()->scheduleNewEntity("Bomb") - .addComponent(position.round()) + .addComponent(position) .addComponent(1, [](WAL::Entity &entity, WAL::Wal &wal) { // the bomb explode when hit entity.scheduleDeletion(); @@ -100,8 +133,35 @@ namespace BBM auto &bombDetails = entity.getComponent(); BombHolderSystem::_dispatchExplosion(pos.position, wal, bombDetails.explosionRadius); }) + .addComponent("assets/shaders/white.fs", "", [](WAL::Entity &entity, WAL::Wal &wal, std::chrono::nanoseconds dtime) { + auto &ctx = entity.getComponent(); + auto &shader = entity.getComponent(); + auto &timer = entity.getComponent(); + + if (ctx.whiteValue >= 1) + ctx.balance = -1; + if (ctx.whiteValue <= 0) + ctx.balance = 1; + auto nbMilliSec = duration_cast(timer.ringIn).count(); + + float step; + + if (nbMilliSec > 1000) { + step = 0.07; + } else if (nbMilliSec > 500) { + step = 0.15; + } else if (nbMilliSec > 100) { + step = 0.26; + } else { + step = 0.5; + } + + ctx.whiteValue += static_cast(step * ctx.balance); + shader.shader.setShaderUniformVar("white", ctx.whiteValue); + }) + .addComponent() .addComponent>() - .addComponent(holder.damage, holder.explosionRadius, id) + .addComponent(holder.damage, holder.explosionRadius, overlapping) .addComponent(BombHolderSystem::explosionTimer, &BombHolderSystem::_bombExplosion) .addComponent( WAL::Callback(), @@ -111,22 +171,15 @@ namespace BBM MAP_DIFFUSE, "assets/bombs/bomb_normal.png" )); - holder.damage = 1; - holder.explosionRadius = 3; } - void - BombHolderSystem::onUpdate(WAL::ViewEntity &entity, - std::chrono::nanoseconds dtime) + void BombHolderSystem::onUpdate(WAL::ViewEntity &entity, + std::chrono::nanoseconds dtime) { auto &holder = entity.get(); auto &position = entity.get(); auto &controllable = entity.get(); - if (controllable.bomb && holder.bombCount > 0) { - holder.bombCount--; - this->_spawnBomb(position.position, holder, entity->getUid()); - } if (holder.bombCount < holder.maxBombCount) { holder.nextBombRefill -= dtime; if (holder.nextBombRefill <= 0ns) { @@ -134,5 +187,14 @@ namespace BBM holder.bombCount++; } } + if (controllable.bomb && holder.bombCount > 0) { + auto spawnPos = position.position.round(); + for (auto &[entity, pos, _] : this->_wal.getScene()->view()) { + if (pos.position == spawnPos) + return; + } + holder.bombCount--; + this->_spawnBomb(spawnPos, holder); + } } } \ No newline at end of file diff --git a/sources/System/BombHolder/BombHolderSystem.hpp b/sources/System/BombHolder/BombHolderSystem.hpp index c5631190..9ba67f2b 100644 --- a/sources/System/BombHolder/BombHolderSystem.hpp +++ b/sources/System/BombHolder/BombHolderSystem.hpp @@ -35,7 +35,7 @@ namespace BBM { private: //! @brief Spawn a bomb at the specified position. - void _spawnBomb(Vector3f position, BombHolderComponent &holder, unsigned id); + void _spawnBomb(Vector3f position, BombHolderComponent &holder); //! @brief Spawn a bomb at the specified position. static void _dispatchExplosion(const Vector3f &position, diff --git a/sources/System/Bonus/BonusUISystem.cpp b/sources/System/Bonus/BonusUISystem.cpp new file mode 100644 index 00000000..d6ac5598 --- /dev/null +++ b/sources/System/Bonus/BonusUISystem.cpp @@ -0,0 +1,17 @@ +// +// Created by hbenjamin on 09/06/2021. +// + +#include "BonusUISystem.hpp" + +namespace BBM +{ + BonusUISystem::BonusUISystem(WAL::Wal &wal) + : System(wal) + {} + + void BonusUISystem::onFixedUpdate(WAL::ViewEntity &entity) + { + entity.get().updater(entity.get()); + } +} \ No newline at end of file diff --git a/sources/System/Bonus/BonusUISystem.hpp b/sources/System/Bonus/BonusUISystem.hpp new file mode 100644 index 00000000..ddc6f95f --- /dev/null +++ b/sources/System/Bonus/BonusUISystem.hpp @@ -0,0 +1,32 @@ +// +// +// + +#pragma once + +#include "System/System.hpp" +#include "Wal.hpp" +#include "Component/Renderer/Drawable2DComponent.hpp" +#include "Component/Stat/StatComponent.hpp" + +namespace BBM +{ + //! @brief The system that allow the text of the ui to display current values + class BonusUISystem : public WAL::System + { + private: + public: + //! @inherit + void onFixedUpdate(WAL::ViewEntity &entity) override; + + //! @brief A default constructor + explicit BonusUISystem(WAL::Wal &wal); + //! @brief A bomb holder system is copy constructable + BonusUISystem(const BonusUISystem &) = default; + //! @brief A default destructor + ~BonusUISystem() override = default; + //! @brief A bomb holder system is not assignable. + BonusUISystem &operator=(const BonusUISystem &) = delete; + }; +} + diff --git a/sources/System/Bonus/PlayerBonusSystem.cpp b/sources/System/Bonus/PlayerBonusSystem.cpp index 69dcfc27..a0fc8218 100644 --- a/sources/System/Bonus/PlayerBonusSystem.cpp +++ b/sources/System/Bonus/PlayerBonusSystem.cpp @@ -18,15 +18,10 @@ namespace BBM auto &holder = entity.get(); auto &playerBonus = entity.get(); - playerBonus.nextSpeedBonusRate -= dtime; - if (playerBonus.nextSpeedBonusRate <= 0ns) { - playerBonus.nextSpeedBonusRate = playerBonus.speedBonusRate; - controllable.speed = 0.25f; - } - playerBonus.nextRangeBonusRate -= dtime; - if (playerBonus.nextRangeBonusRate <= 0ns) { - playerBonus.nextRangeBonusRate = playerBonus.rangeBonusRate; - holder.explosionRadius = 3; + playerBonus.nextNoClipRate -= dtime; + if (playerBonus.nextNoClipRate <= 0ns) { + playerBonus.nextNoClipRate = playerBonus.noClipBonusRate; + playerBonus.isNoClipOn = false; } } } \ No newline at end of file diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index f2604254..85e0e009 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -7,7 +7,6 @@ #include "Component/Collision/CollisionComponent.hpp" #include "System/Collision/CollisionSystem.hpp" #include "Scene/Scene.hpp" - namespace BBM { CollisionSystem::CollisionSystem(WAL::Wal &wal) @@ -64,25 +63,25 @@ namespace BBM continue; auto pointB = posB.position + colB.positionOffset; - int collidedAxis = 0; + CollisionComponent::CollidedAxis collidedAxis = CollisionComponent::NONE; // TODO if B is also a movable we don't check with it's changing position Vector3f minB = Vector3f::min(pointB, pointB + colB.bound); Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound); if (boxesCollide(minAx, maxAx, minB, maxB)) { - collidedAxis += vel.isNull() ? 7 : CollisionComponent::CollidedAxis::X; + collidedAxis |= vel.isNull() ? CollisionComponent::ALL : CollisionComponent::X; } if (!vel.isNull()) { if (boxesCollide(minAy, maxAy, minB, maxB)) { - collidedAxis += CollisionComponent::CollidedAxis::Y; + collidedAxis |= CollisionComponent::Y; } if (boxesCollide(minAz, maxAz, minB, maxB)) { - collidedAxis += CollisionComponent::CollidedAxis::Z; + collidedAxis |= CollisionComponent::Z; } } if (collidedAxis) { - colA.onCollide(entity, other, static_cast(collidedAxis)); - colB.onCollided(entity, other, static_cast(collidedAxis)); + colA.onCollide(entity, other, collidedAxis); + colB.onCollided(entity, other, collidedAxis); } } } diff --git a/sources/System/EndCondition/EndConditionSystem.cpp b/sources/System/EndCondition/EndConditionSystem.cpp new file mode 100644 index 00000000..fdabe35a --- /dev/null +++ b/sources/System/EndCondition/EndConditionSystem.cpp @@ -0,0 +1,26 @@ + +#include "EndConditionSystem.hpp" +#include +#include "Runner/Runner.hpp" +#include "Component/Score/ScoreComponent.hpp" + +namespace BBM +{ + + EndConditionSystem::EndConditionSystem(WAL::Wal &wal) + : System(wal) + {} + + void EndConditionSystem::onSelfUpdate() + { + unsigned int alivePlayersCount = 0; + auto &view = this->_wal.getScene()->view(); + + if (!view.size()) + return; + for (auto &[_, scoreComponent, healthComponent]: view) + alivePlayersCount += (healthComponent.getHealthPoint() != 0); + if (alivePlayersCount <= 1) + Runner::gameState.nextScene = Runner::gameState.ScoreScene; + } +} \ No newline at end of file diff --git a/sources/System/EndCondition/EndConditionSystem.hpp b/sources/System/EndCondition/EndConditionSystem.hpp new file mode 100644 index 00000000..edd3a9d7 --- /dev/null +++ b/sources/System/EndCondition/EndConditionSystem.hpp @@ -0,0 +1,26 @@ + +#pragma once + +#include "System/System.hpp" +#include "Component/Score/ScoreComponent.hpp" +#include "Component/Health/HealthComponent.hpp" +#include "Wal.hpp" + +namespace BBM +{ + class EndConditionSystem : public WAL::System + { + public: + //! @inherit + void onSelfUpdate() override; + + //! @brief ctor + EndConditionSystem(WAL::Wal &wal); + //! @brief Default copy ctor + EndConditionSystem(const EndConditionSystem &) = default; + //! @brief Default dtor + ~EndConditionSystem() override = default; + //! @brief A SoundManager screen system can't be assigned. + EndConditionSystem &operator=(const EndConditionSystem &) = delete; + }; +} diff --git a/sources/System/IAControllable/IAControllableSystem.cpp b/sources/System/IAControllable/IAControllableSystem.cpp new file mode 100644 index 00000000..26432c1f --- /dev/null +++ b/sources/System/IAControllable/IAControllableSystem.cpp @@ -0,0 +1,181 @@ +// +// Created by Louis Auzuret on 06/07/21 +// + +#include "Component/Bomb/BasicBombComponent.hpp" +#include "Component/Tag/TagComponent.hpp" +#include "Component/Timer/TimerComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Component/IAControllable/IAControllableComponent.hpp" +#include "System/IAControllable/IAControllableSystem.hpp" +#include + +namespace BBM +{ + IAControllableSystem::IAControllableSystem(WAL::Wal &wal) + : System(wal), _wal(wal), _cached(false) + { } + + void IAControllableSystem::UpdateMapInfos(WAL::ViewEntity &entity) + { + _players.clear(); + for (auto &[other, pos, _] : _wal.getScene()->view>()) { + if (static_cast(entity).getUid() == other.getUid()) + continue; + _players.push_back(MapInfo(pos.position, MapGenerator::NOTHING)); + } + if (_cached) + return; + if (!_wal.getScene()) + return; + for (auto &[other, pos, _] : _wal.getScene()->view>()) + _map.push_back(MapInfo(pos.position, MapGenerator::BREAKABLE)); + for (auto &[other, pos, _] : _wal.getScene()->view>()) + _map.push_back(MapInfo(pos.position, MapGenerator::UNBREAKABLE)); + for (auto &[other, pos, _] : _wal.getScene()->view>()) + _map.push_back(MapInfo(pos.position, MapGenerator::BUMPER)); + for (auto &[other, pos, _] : _wal.getScene()->view>()) + _map.push_back(MapInfo(pos.position, MapGenerator::HOLE)); + for (auto &[other, pos, bomb, timer] : _wal.getScene()->view()) + _bombs.push_back(std::make_tuple(pos.position, bomb.explosionRadius, timer.ringIn)); + _cached = true; + + } + + void IAControllableSystem::pushInfoPlayer(LuaG::State &state, MapInfo &player, BombHolderComponent &bombHolder) + { + state.push("player"); + state.newTable(); + state.push("x"); + state.push(player.x); + state.setTable(); + state.push("y"); + state.push(player.z); + state.setTable(); + state.push("bombCount"); + state.push(bombHolder.bombCount); + state.setTable(); + state.push("radius"); + state.push(bombHolder.explosionRadius); + state.setTable(); + state.setTable(); + } + + void IAControllableSystem::pushInfoRaw(LuaG::State &state) + { + int index = 0; + state.push("raw"); + state.newTable(); + for (auto &info : _map) { + state.push(index++); + state.newTable(); + state.push("x"); + state.push(info.x); + state.setTable(); + state.push("y"); + state.push(info.z); + state.setTable(); + state.push("type"); + state.push(info.type); + state.setTable(); + state.setTable(); + } + for (auto &bomb : _bombs) { + Vector3f bombPos = std::get<0>(bomb); + state.push(index++); + state.newTable(); + state.push("x"); + state.push(bombPos.x); + state.setTable(); + state.push("y"); + state.push(bombPos.z); + state.setTable(); + state.push("type"); + state.push(10); + state.setTable(); + state.setTable(); + } + state.setTable(); + } + + void IAControllableSystem::pushInfoDangerPos(LuaG::State &state, int &index, float xpos, float ypos, int dangerLevel) + { + state.push(index++); + state.newTable(); + state.push("x"); + state.push(xpos); + state.setTable(); + state.push("y"); + state.push(ypos); + state.setTable(); + state.push("level"); + state.push(dangerLevel); + state.setTable(); + state.setTable(); + } + + void IAControllableSystem::pushInfoDanger(LuaG::State &state) + { + int index = 0; + state.push("danger"); + state.newTable(); + for (auto &bomb : _bombs) { + Vector3f bombPos = std::get<0>(bomb); + int bombRadius = std::get<1>(bomb); + std::chrono::nanoseconds timeleft = std::get<2>(bomb); + int dangerLevel = std::chrono::duration_cast(timeleft).count(); + if (dangerLevel == 0) + dangerLevel = 1; + pushInfoDangerPos(state, index, bombPos.x, bombPos.z, dangerLevel); + pushInfoDangerPos(state, index, bombPos.x, bombPos.z, dangerLevel); + for (int i = 1; i < bombRadius; i++) { + Vector3f pos = bombPos - Vector3f(i, 0, 0); + pushInfoDangerPos(state, index, pos.x, pos.z, dangerLevel); + pos = bombPos - Vector3f(-i, 0, 0); + pushInfoDangerPos(state, index, pos.x, pos.z, dangerLevel); + pos = bombPos - Vector3f(0, 0, i); + pushInfoDangerPos(state, index, pos.x, pos.z, dangerLevel); + pos = bombPos - Vector3f(0, 0, -i); + pushInfoDangerPos(state, index, pos.x, pos.z, dangerLevel); + } + } + state.setTable(); + } + + void IAControllableSystem::pushInfo(LuaG::State &state, MapInfo &player, BombHolderComponent &bombHolder) + { + state.newTable(); + pushInfoPlayer(state, player, bombHolder); + pushInfoRaw(state); + pushInfoDanger(state); + } + + void IAControllableSystem::onFixedUpdate(WAL::ViewEntity &entity) + { + auto &ia = entity.get(); + auto &controllable = entity.get(); + auto &pos = entity.get(); + auto &bombHolder = entity.get(); + MapInfo player(pos.position, MapGenerator::NOTHING); + + UpdateMapInfos(entity); + + ia._state.getGlobal("Update"); + if (!lua_isfunction(ia._state.getState(), -1)) + return; + pushInfo(ia._state, player, bombHolder); + ia._state.callFunction(1, 4); + controllable.bomb = ia._state.getReturnBool(); + controllable.select = ia._state.getReturnBool(); + controllable.move.y = ia._state.getReturnNumber(); + controllable.move.x = ia._state.getReturnNumber(); + ia._state.popLast(); + } + + void IAControllableSystem::onSelfUpdate() + { + _cached = false; + _map.clear(); + _bombs.clear(); + } +} \ No newline at end of file diff --git a/sources/System/IAControllable/IAControllableSystem.hpp b/sources/System/IAControllable/IAControllableSystem.hpp new file mode 100644 index 00000000..6c895a25 --- /dev/null +++ b/sources/System/IAControllable/IAControllableSystem.hpp @@ -0,0 +1,67 @@ +// +// Created by Louis Auzuret on 06/07/21 +// + +#pragma once + +#include +#include "Component/BombHolder/BombHolderComponent.hpp" +#include "Map/MapInfo.hpp" +#include "System/System.hpp" + +namespace BBM +{ + //! @brief A system to handle keyboard entities. + class IAControllableSystem : public WAL::System + { + private: + //! @brief Reference to wal to get Views + WAL::Wal &_wal; + + //! @brief Are the infos cached for current update + bool _cached; + + //! @brief All blocks in the map + std::vector _map; + + //! @brief All players in the map + std::vector _players; + + //! @brief All bombs on the map + std::vector> _bombs; + + //! @brief update the raw info of the map + void UpdateMapInfos(WAL::ViewEntity &entity); + + //! @brief push danger info position + void pushInfoDangerPos(LuaG::State &state, int &index, float xpos, float ypos, int dangerLevel); + + //! @brief push player info + void pushInfoPlayer(LuaG::State &state, MapInfo &player, BombHolderComponent &bombHolder); + + //! @brief push raw map info + void pushInfoRaw(LuaG::State &state); + + //! @brief push danger map info + void pushInfoDanger(LuaG::State &state); + + //! @brief push all the infos to the lua stack + void pushInfo(LuaG::State &state, MapInfo &player, BombHolderComponent &bombHolder); + public: + + //! @inherit + void onFixedUpdate(WAL::ViewEntity &entity) override; + + //! @inherit + void onSelfUpdate() override; + + //! @brief A default constructor + IAControllableSystem(WAL::Wal &wal); + //! @brief A keyboard system is copy constructable + IAControllableSystem(const IAControllableSystem &) = default; + //! @brief A default destructor + ~IAControllableSystem() override = default; + //! @brief A keyboard system is assignable. + IAControllableSystem &operator=(const IAControllableSystem &) = default; + }; +} diff --git a/sources/System/Lobby/LobbySystem.cpp b/sources/System/Lobby/LobbySystem.cpp index 7ad06983..cbb33c7e 100644 --- a/sources/System/Lobby/LobbySystem.cpp +++ b/sources/System/Lobby/LobbySystem.cpp @@ -12,10 +12,18 @@ #include #include #include +#include "Component/IAControllable/IAControllableComponent.hpp" #include #include +#include +#include +#include "Component/Color/ColorComponent.hpp" +#include "Component/Stat/StatComponent.hpp" +#include "Component/Bonus/PlayerBonusComponent.hpp" +#include "Component/BombHolder/BombHolderComponent.hpp" namespace RAY3D = RAY::Drawables::Drawables3D; +namespace RAY2D = RAY::Drawables::Drawables2D; namespace BBM { @@ -185,7 +193,7 @@ namespace BBM player.addComponent(3); break; case ControllableComponent::AI: - throw std::runtime_error("Not implemented error"); + player.addComponent("./assets/ai_scripts/john.lua"); break; default: throw std::runtime_error("Invalid controller for a player."); @@ -205,10 +213,71 @@ namespace BBM auto &player = Runner::createPlayer(*scene); _addController(player, lobby.layout); player.getComponent().position = Vector3f(mapWidth * (playerCount % 2), - 0, - mapHeight * ((playerCount + 1) % 2)); + (Runner::hasHeights ? 1.01 : 0), + mapHeight * (!(playerCount % 3))); auto *model = dynamic_cast(player.getComponent().drawable.get()); model->setTextureToMaterial(MAP_DIFFUSE, "assets/player/textures/" + _colors[lobby.color] + ".png"); + std::string texturePath = "assets/player/ui/" + _colors[lobby.color] + ".png"; + int x = (playerCount % 2 == 0) ? 1920 - 10 - 320 : 10; + int y = (playerCount % 3 != 0) ? 1080 - 10 - 248 : 10; + scene->addEntity("player color tile") + .addComponent(x, y - 2, 0) + .addComponent(x, y, 320, 248, _rayColors[lobby.color]); + scene->addEntity("player ui tile") + .addComponent(x, y, 0) + .addComponent(texturePath); + scene->addEntity("player hide fireup") + .addComponent(x + 220, y + 35, 0) + .addComponent("", 20, x, y, WHITE) + .addComponent([&player](Drawable2DComponent &drawble) { + const BombHolderComponent *bonus = player.tryGetComponent(); + + if (!bonus) + return; + RAY2D::Text *text = dynamic_cast(drawble.drawable.get()); + if (!text) + return; + text->setText(std::to_string(bonus->explosionRadius)); + }); + scene->addEntity("player hide bombup") + .addComponent(x + 220, y + 77, 0) + .addComponent("", 20, x, y, WHITE) + .addComponent([&player](Drawable2DComponent &drawble) { + const BombHolderComponent *bonus = player.tryGetComponent(); + + if (!bonus) + return; + RAY2D::Text *text = dynamic_cast(drawble.drawable.get()); + if (!text) + return; + text->setText(std::to_string(bonus->bombCount) + " / " + std::to_string(bonus->maxBombCount)); + }); + scene->addEntity("player hide speedup") + .addComponent(x + 220, y + 122, 0) + .addComponent("", 20, x, y, WHITE) + .addComponent([&player](Drawable2DComponent &drawble) { + const ControllableComponent *bonus = player.tryGetComponent(); + + if (!bonus) + return; + RAY2D::Text *text = dynamic_cast(drawble.drawable.get()); + if (!text) + return; + text->setText(std::to_string(static_cast(bonus->speed * 100))); + }); + scene->addEntity("player hide wall") + .addComponent(x + 220, y + 161, 0) + .addComponent("", 20, x, y, WHITE) + .addComponent([&player](Drawable2DComponent &drawble) { + const PlayerBonusComponent *bonus = player.tryGetComponent(); + + if (!bonus) + return; + RAY2D::Text *text = dynamic_cast(drawble.drawable.get()); + if (!text) + return; + text->setText(bonus->isNoClipOn ? "YES" : "NO"); + }); playerCount++; } Runner::gameState._loadedScenes[GameState::SceneID::GameScene] = scene; diff --git a/sources/System/MenuControllable/MenuControllableSystem.cpp b/sources/System/MenuControllable/MenuControllableSystem.cpp index d70ae7bc..96dcb341 100644 --- a/sources/System/MenuControllable/MenuControllableSystem.cpp +++ b/sources/System/MenuControllable/MenuControllableSystem.cpp @@ -7,13 +7,20 @@ #include "System/MenuControllable/MenuControllableSystem.hpp" #include "Component/Controllable/ControllableComponent.hpp" #include "Entity/Entity.hpp" +#include "Drawables/Texture.hpp" +#include "Drawables/2D/Text.hpp" +#include "Controllers/Mouse.hpp" + +namespace RAYControl = RAY::Controller; +namespace RAY2D = RAY::Drawables::Drawables2D; namespace BBM { MenuControllableSystem::MenuControllableSystem(WAL::Wal &wal) : System(wal), - _currentButton() - {} + _currentButton(), _oldMousePosition(-1, -1) + { + } void MenuControllableSystem::_updateCurrentButton(bool selected, Vector2f move) { @@ -45,14 +52,41 @@ namespace BBM this->_currentButton->getComponent().onEvent(*this->_currentButton, this->_wal); } - void MenuControllableSystem::onFixedUpdate(WAL::ViewEntity &entity) + bool MenuControllableSystem::_mouseOnButton(const Vector2f &mousePos, WAL::ViewEntity &entity) const { - auto &controllable = entity.get(); - auto &buttons = _wal.getScene()->view(); + auto &positionComponent = entity.get(); + RAY::Texture *texture = dynamic_cast(entity.get().drawable.get()); + RAY2D::Text *text = dynamic_cast(entity.get().drawable.get()); + Vector2f buttonPos(positionComponent.getX(), positionComponent.getY()); + Vector2f dimensions; + if (texture) { + dimensions.x = texture->getDimensions().x; + dimensions.y = texture->getDimensions().y; + } else if (text) { + dimensions.y = text->getFontSize(); + dimensions.x = text->getString().size() * (text->getFontSize()); + } else + return false; + return ((buttonPos.x <= mousePos.x && mousePos.x <= buttonPos.x + dimensions.x) + && (buttonPos.y <= mousePos.y && mousePos.y <= buttonPos.y + dimensions.y)); + } + + void MenuControllableSystem::onSelfUpdate() + { + RAY::Vector2 rayMousePos = RAYControl::Mouse::getCursorPosition(); + RAY::Vector2 winSize = RAY::Window::getInstance().getDimensions(); + Vector2f relativeMousePos(rayMousePos.x * 1920 / winSize.x, rayMousePos.y * 1080 / winSize.y); + auto &controllableView = this->_wal.getScene()->view(); + auto &buttons = _wal.getScene()->view(); + + + if (this->_oldMousePosition == Vector2f(-1, -1)) + this->_oldMousePosition = relativeMousePos; if (this->_currentButton && this->_currentButton->_scene.getID() != this->_wal.getScene()->getID()) { this->_currentButton->getComponent().onEvent(*this->_currentButton, this->_wal); this->_currentButton = nullptr; + return; } if (this->_currentButton == nullptr && buttons.size()) { this->_currentButton = &(*buttons.front()); @@ -60,6 +94,23 @@ namespace BBM } if (!this->_currentButton) return; - this->_updateCurrentButton(controllable.select, controllable.move); + for (auto &[_, controllable]: controllableView) + if (controllable.move.x || controllable.move.y || controllable.select) { + this->_updateCurrentButton(controllable.select, controllable.move); + return; + } + if (relativeMousePos == this->_oldMousePosition && !RAYControl::Mouse::isPressed(RAYControl::Mouse::Button::MOUSE_BUTTON_LEFT)) + return; + this->_oldMousePosition = relativeMousePos; + for (auto &entity: buttons) { + if (_mouseOnButton(relativeMousePos, entity)) { + if (this->_currentButton) + this->_currentButton->getComponent().onEvent(*this->_currentButton, this->_wal); + this->_currentButton = &(*entity); + this->_currentButton->getComponent().onEvent(*this->_currentButton, this->_wal); + if (RAYControl::Mouse::isPressed(RAYControl::Mouse::Button::MOUSE_BUTTON_LEFT)) + this->_currentButton->getComponent().onEvent(*this->_currentButton, this->_wal); + } + } } } \ No newline at end of file diff --git a/sources/System/MenuControllable/MenuControllableSystem.hpp b/sources/System/MenuControllable/MenuControllableSystem.hpp index 0ad43a45..7462a358 100644 --- a/sources/System/MenuControllable/MenuControllableSystem.hpp +++ b/sources/System/MenuControllable/MenuControllableSystem.hpp @@ -7,25 +7,33 @@ #include "Component/Controllable/ControllableComponent.hpp" #include "Models/Vector2.hpp" #include "System/System.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/Renderer/Drawable2DComponent.hpp" +#include "Component/Button/ButtonComponent.hpp" namespace BBM { //! @brief A system to handle Controllable entities in a menu. - class MenuControllableSystem : public WAL::System + class MenuControllableSystem : public WAL::System<> { private: //! @brief index of the current button selected WAL::Entity *_currentButton; + //! @brief position of the mouse at the precedent scene (to know which controller event to watch) + Vector2f _oldMousePosition; + //! @brief update current button reference //! @param selected lets know if te new selected button is 'pressed' void _updateCurrentButton(bool selected, Vector2f move); + //! @return true if mouse on entity + bool _mouseOnButton(const Vector2f &mousePos, WAL::ViewEntity &entity) const; public: //! @brief time (in millisecond) since last check std::chrono::time_point now; //! @inherit - void onFixedUpdate(WAL::ViewEntity &entities) override; + void onSelfUpdate() override; //! @brief A default constructor explicit MenuControllableSystem(WAL::Wal &wal); diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index 483bb9f6..3c290311 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -10,11 +10,16 @@ #include "Component/Renderer/Drawable2DComponent.hpp" #include #include "Drawables/ADrawable3D.hpp" +#include "Drawables/ADrawable2D.hpp" #include "Component/Shaders/ShaderComponent.hpp" #include "Component/Tag/TagComponent.hpp" #include #include "Models/Vector3.hpp" #include "Component/Collision/CollisionComponent.hpp" +#include +#include + +namespace RAY2D = RAY::Drawables::Drawables2D; namespace BBM { @@ -41,11 +46,86 @@ namespace BBM drawable.drawable->drawWiresOn(this->_window); } + Vector2f RenderSystem::getRescaledPosition(Vector3f &position, const Vector2f &newWinDims) + { + Vector2f newPosition; + newPosition.x = (position.x * newWinDims.x) / 1920; + newPosition.y = (position.y * newWinDims.y) / 1080; + return newPosition; + } + + void RenderSystem::drawRescaledDrawable(RAY::Drawables::ADrawable2D &drawable, const Vector2f &newDims) + { + RAY2D::Text *text = dynamic_cast(&drawable); + + if (text) { + float oldHeightSize = text->getFontSize(); + float oldWidthSize = text->getFontSize() + text->getLetterSpacing(); + float newHeightSize = oldHeightSize * newDims.y / 1080; + float newWidthSize = oldWidthSize * newDims.x / 1920; + text->setFontSize((newWidthSize + newHeightSize) / 2); + drawable.drawOn(this->_window); + text->setFontSize(oldHeightSize); + return; + } + RAY::Texture *texture = dynamic_cast(&drawable); + + if (texture) { + float oldScale = texture->getScale(); + float newScale = (texture->getWidth() * newDims.x / 1920) / texture->getWidth(); + texture->setScale(newScale); + drawable.drawOn(this->_window); + texture->setScale(oldScale); + return; + } + RAY2D::Rectangle *rect = dynamic_cast(&drawable); + + if (rect) { + float oldHeightSize = rect->getHeight(); + float oldWidthSize = rect->getWidth(); + rect->setHeight(oldHeightSize * newDims.y / 1080); + rect->setWidth(oldWidthSize * newDims.x / 1920); + drawable.drawOn(this->_window); + rect->setWidth(oldWidthSize); + rect->setHeight(oldHeightSize); + return; + } + } + + void RenderSystem::resizeWindow(Vector2f &newDims) + { + newDims.y = (newDims.x * 720) / 1280; + if ((newDims.y < 720 || newDims.x < 1280)) { + newDims.y = 720; + newDims.x = 1280; + } + this->_window.setDimensions(newDims); + } + void RenderSystem::onSelfUpdate() { this->_camera.update(); this->_window.beginDrawing(); this->_window.clear(); + RAY::Vector2 rayWinDims = this->_window.getDimensions(); + Vector2f windowDimensions(rayWinDims.x, rayWinDims.y); + + this->resizeWindow(windowDimensions); + + for (auto &[entity, pos, drawable] : this->_wal.getScene()->view()) { + if (!drawable.drawBefore3D) + continue; + auto *shader = entity.tryGetComponent(); + + if (shader) { + RAY::Shader::BeginUsingCustomShader(shader->getShader()); + } + drawable.drawable->setPosition(Vector2f(pos.position.x, pos.position.y)); + drawable.drawable->drawOn(this->_window); + if (shader) { + RAY::Shader::EndUsingCustomShader(); + } + } this->_window.useCamera(this->_camera); for (auto &[entity, pos, drawable] : this->_wal.getScene()->view()) { @@ -64,13 +144,15 @@ namespace BBM // TODO sort entities based on the Z axis for (auto &[entity, pos, drawable] : this->_wal.getScene()->view()) { + if (drawable.drawBefore3D) + continue; auto *shader = entity.tryGetComponent(); if (shader) { RAY::Shader::BeginUsingCustomShader(shader->getShader()); } - drawable.drawable->setPosition(Vector2f(pos.position.x, pos.position.y)); - drawable.drawable->drawOn(this->_window); + drawable.drawable->setPosition(this->getRescaledPosition(pos.position, windowDimensions)); + this->drawRescaledDrawable(*drawable.drawable, windowDimensions); if (shader) { RAY::Shader::EndUsingCustomShader(); } diff --git a/sources/System/Renderer/RenderSystem.hpp b/sources/System/Renderer/RenderSystem.hpp index fcb40970..ea1c3b3f 100644 --- a/sources/System/Renderer/RenderSystem.hpp +++ b/sources/System/Renderer/RenderSystem.hpp @@ -12,6 +12,7 @@ #include "Camera/Camera2D.hpp" #include "Window.hpp" #include "Wal.hpp" +#include "Models/Vector2.hpp" namespace BBM { @@ -30,6 +31,18 @@ namespace BBM //! @brief Window framerate limit static constexpr short FPS = 60; + //! @brief rescale the drawables dimensions according to new window dimensions + //! @param drawable the drawable to rescale + //! @param newDims the new window's dimensions + void drawRescaledDrawable(RAY::Drawables::ADrawable2D &drawable, const Vector2f &newDims); + + //! @brief rescale the drawables position according to new window dimensions + //! @param position a reference to position + //! @param newDims the new window's dimensions + Vector2f getRescaledPosition(Vector3f &position, const Vector2f &newWinDims); + + void resizeWindow(Vector2f &newDims); + public: //! @brief A method called after all entities that this system manage has been updated. //! @note render on screen here diff --git a/sources/System/Score/ScoreSystem.cpp b/sources/System/Score/ScoreSystem.cpp new file mode 100644 index 00000000..4b32fda2 --- /dev/null +++ b/sources/System/Score/ScoreSystem.cpp @@ -0,0 +1,19 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#include "ScoreSystem.hpp" +#include + +namespace BBM { + + ScoreSystem::ScoreSystem(WAL::Wal &wal) + : System(wal) + {} + + void ScoreSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + { + if (entity.get().getHealthPoint()) + entity.get().aliveTime += dtime; + } +} \ No newline at end of file diff --git a/sources/System/Score/ScoreSystem.hpp b/sources/System/Score/ScoreSystem.hpp new file mode 100644 index 00000000..33ad3c95 --- /dev/null +++ b/sources/System/Score/ScoreSystem.hpp @@ -0,0 +1,26 @@ + +#pragma once + +#include "System/System.hpp" +#include "Component/Score/ScoreComponent.hpp" +#include "Component/Health/HealthComponent.hpp" +#include "Wal.hpp" + +namespace BBM +{ + class ScoreSystem : public WAL::System + { + public: + //! @inherit + void onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief ctor + ScoreSystem(WAL::Wal &wal); + //! @brief Default copy ctor + ScoreSystem(const ScoreSystem &) = default; + //! @brief Default dtor + ~ScoreSystem() override = default; + //! @brief A SoundManager screen system can't be assigned. + ScoreSystem &operator=(const ScoreSystem &) = delete; + }; +} diff --git a/sources/System/Shaders/ShaderDrawable2DSystem.cpp b/sources/System/Shaders/ShaderDrawable2DSystem.cpp new file mode 100644 index 00000000..c8e7ae8d --- /dev/null +++ b/sources/System/Shaders/ShaderDrawable2DSystem.cpp @@ -0,0 +1,20 @@ +// +// Created by cbihan on 15/06/2021. +// + +#include "ShaderDrawable2DSystem.hpp" + +namespace BBM +{ + ShaderDrawable2DSystem::ShaderDrawable2DSystem(WAL::Wal &wal) + : System(wal) + { + } + + void ShaderDrawable2DSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + { + auto &shader = entity->getComponent(); + + shader.update(entity, this->_wal, dtime); + } +} \ No newline at end of file diff --git a/sources/System/Shaders/ShaderDrawable2DSystem.hpp b/sources/System/Shaders/ShaderDrawable2DSystem.hpp new file mode 100644 index 00000000..59d22534 --- /dev/null +++ b/sources/System/Shaders/ShaderDrawable2DSystem.hpp @@ -0,0 +1,29 @@ +// +// Created by cbihan on 15/06/2021. +// + +#pragma once + +#include "Component/Shaders/ShaderComponent.hpp" +#include "System/System.hpp" +#include "Wal.hpp" + +namespace BBM +{ + class ShaderDrawable2DSystem : public WAL::System + { + public: + + //! @inherit + void onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief ctor + explicit ShaderDrawable2DSystem(WAL::Wal &wal); + //! @brief Default copy ctor + ShaderDrawable2DSystem(const ShaderDrawable2DSystem &) = default; + //! @brief Default dtor + ~ShaderDrawable2DSystem() override = default; + //! @brief A render screen system can't be assigned. + ShaderDrawable2DSystem &operator=(const ShaderDrawable2DSystem &) = delete; + }; +} \ No newline at end of file diff --git a/sources/System/Shaders/ShaderModelSystem.cpp b/sources/System/Shaders/ShaderModelSystem.cpp new file mode 100644 index 00000000..07baa38a --- /dev/null +++ b/sources/System/Shaders/ShaderModelSystem.cpp @@ -0,0 +1,20 @@ +// +// Created by cbihan on 15/06/2021. +// + +#include "ShaderModelSystem.hpp" + +namespace BBM +{ + ShaderModelSystem::ShaderModelSystem(WAL::Wal &wal) + : System(wal) + { + } + + void ShaderModelSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + { + auto &shader = entity->getComponent(); + + shader.update(entity, this->_wal, dtime); + } +} \ No newline at end of file diff --git a/sources/System/Shaders/ShaderModelSystem.hpp b/sources/System/Shaders/ShaderModelSystem.hpp new file mode 100644 index 00000000..7680e88f --- /dev/null +++ b/sources/System/Shaders/ShaderModelSystem.hpp @@ -0,0 +1,29 @@ +// +// Created by cbihan on 15/06/2021. +// + +#pragma once + +#include "ShaderSystem.hpp" +#include "System/System.hpp" +#include "Wal.hpp" + +namespace BBM +{ + class ShaderModelSystem : public WAL::System + { + public: + + //! @inherit + void onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief ctor + explicit ShaderModelSystem(WAL::Wal &wal); + //! @brief Default copy ctor + ShaderModelSystem(const ShaderModelSystem &) = default; + //! @brief Default dtor + ~ShaderModelSystem() override = default; + //! @brief A render screen system can't be assigned. + ShaderModelSystem &operator=(const ShaderModelSystem &) = delete; + }; +} \ No newline at end of file diff --git a/sources/System/Shaders/ShaderSystem.cpp b/sources/System/Shaders/ShaderSystem.cpp new file mode 100644 index 00000000..8a86e3b6 --- /dev/null +++ b/sources/System/Shaders/ShaderSystem.cpp @@ -0,0 +1,21 @@ +// +// Created by cbihan on 15/06/2021. +// + +#include "ShaderSystem.hpp" + + +namespace BBM +{ + ShaderSystem::ShaderSystem(WAL::Wal &wal) + : System(wal) + { + } + + void ShaderSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + { + auto &shader = entity->getComponent(); + + shader.update(entity, this->_wal, dtime); + } +} \ No newline at end of file diff --git a/sources/System/Shaders/ShaderSystem.hpp b/sources/System/Shaders/ShaderSystem.hpp new file mode 100644 index 00000000..874505d0 --- /dev/null +++ b/sources/System/Shaders/ShaderSystem.hpp @@ -0,0 +1,28 @@ +// +// Created by cbihan on 15/06/2021. +// + +#pragma once + +#include "Component/Shaders/ShaderComponent.hpp" +#include "System/System.hpp" + +namespace BBM +{ + class ShaderSystem : public WAL::System + { + public: + + //! @inherit + void onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief ctor + explicit ShaderSystem(WAL::Wal &wal); + //! @brief Default copy ctor + ShaderSystem(const ShaderSystem &) = default; + //! @brief Default dtor + ~ShaderSystem() override = default; + //! @brief A render screen system can't be assigned. + ShaderSystem &operator=(const ShaderSystem &) = delete; + }; +} \ No newline at end of file diff --git a/sources/System/Timer/TimerSystem.cpp b/sources/System/Timer/TimerSystem.cpp index f6c82c2b..3760534c 100644 --- a/sources/System/Timer/TimerSystem.cpp +++ b/sources/System/Timer/TimerSystem.cpp @@ -4,6 +4,7 @@ #include "TimerSystem.hpp" #include "Component/Timer/TimerComponent.hpp" +#include "Drawables/2D/Text.hpp" using namespace std::chrono_literals; diff --git a/sources/System/Timer/TimerSystem.hpp b/sources/System/Timer/TimerSystem.hpp index c7b20bc2..2be1c1f7 100644 --- a/sources/System/Timer/TimerSystem.hpp +++ b/sources/System/Timer/TimerSystem.hpp @@ -7,6 +7,7 @@ #include #include #include +#include "Component/Renderer/Drawable2DComponent.hpp" namespace BBM { diff --git a/sources/System/Timer/TimerUISystem.cpp b/sources/System/Timer/TimerUISystem.cpp new file mode 100644 index 00000000..a1f4cfa4 --- /dev/null +++ b/sources/System/Timer/TimerUISystem.cpp @@ -0,0 +1,30 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#include "TimerUISystem.hpp" +#include "Component/Timer/TimerComponent.hpp" +#include "Drawables/2D/Text.hpp" + +using namespace std::chrono_literals; +namespace RAY2D = RAY::Drawables::Drawables2D; + +namespace BBM +{ + TimerUISystem::TimerUISystem(WAL::Wal &wal) + : System(wal) + {} + + void TimerUISystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) + { + auto &timer = entity.get(); + RAY2D::Text *text = dynamic_cast(entity.get().drawable.get()); + + if (text) { + unsigned long second = std::chrono::duration_cast(timer.ringIn).count(); + unsigned long minutes = second / 60; + second = second % 60; + text->setText(std::to_string(minutes) + ":" + std::to_string(second)); + } + } +} \ No newline at end of file diff --git a/sources/System/Timer/TimerUISystem.hpp b/sources/System/Timer/TimerUISystem.hpp new file mode 100644 index 00000000..c21a0300 --- /dev/null +++ b/sources/System/Timer/TimerUISystem.hpp @@ -0,0 +1,29 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#pragma once + +#include +#include +#include +#include "Component/Renderer/Drawable2DComponent.hpp" + +namespace BBM +{ + class TimerUISystem : public WAL::System + { + public: + //! @inherit + void onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) override; + + //! @brief A default constructor + TimerUISystem(WAL::Wal &); + //! @brief A timer system is copy constructable. + TimerUISystem(const TimerUISystem &) = default; + //! @brief A default destructor + ~TimerUISystem() override = default; + //! @breief A timer system is assignable. + TimerUISystem &operator=(const TimerUISystem &) = default; + }; +} diff --git a/sources/main.cpp b/sources/main.cpp index c4e69c4a..9cf4bf85 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -23,5 +23,10 @@ int main(int argc, char **argv) usage(argv[0]); return 1; } - return BBM::Runner::run(); + try { + return BBM::Runner::run(); + } catch (const std::exception &ex) { + std::cerr << ex.what() << std::endl; + return 84; + } }