├── .clang-format ├── .cproject ├── .gitattributes ├── .gitignore ├── .gitmodules ├── .project ├── CMake ├── AddressSanitizer.cmake ├── FindSDL2.cmake ├── FindSDL2_gfx.cmake ├── FindSDL2_image.cmake ├── FindSDL2_mixer.cmake ├── FindSDL2_ttf.cmake ├── SDL2_net.cmake ├── ThreadSanitizer.cmake ├── lua.cmake └── readerwriterqueue.cmake ├── CMakeLists.txt ├── CMakeSettings.json ├── LICENSE.txt ├── README.md ├── Resources ├── EngineDefaults │ └── Common │ │ └── Assets │ │ └── Textures │ │ └── Defaults │ │ └── Icon.png └── ResourceImporter │ ├── Common │ └── Assets │ │ ├── Fonts │ │ └── B612-Regular.ttf │ │ └── Textures │ │ ├── Checkbox │ │ ├── Checked.png │ │ └── Unchecked.png │ │ ├── Dialogs │ │ └── Shadow.png │ │ ├── HamburgerButton │ │ ├── Hovered.png │ │ ├── Normal.png │ │ └── Pressed.png │ │ ├── HeaderBackground.png │ │ ├── Highlights │ │ ├── Hovered.png │ │ └── Selected.png │ │ ├── Icons │ │ ├── Collapsed_1600.png │ │ ├── Collapsed_1920.png │ │ ├── Expanded_1600.png │ │ ├── Expanded_1920.png │ │ ├── Minus.png │ │ ├── MinusHovered.png │ │ ├── Plus.png │ │ └── PlusHovered.png │ │ ├── MainButton │ │ ├── Disabled.png │ │ ├── DisabledThick.png │ │ ├── Hovered.png │ │ ├── HoveredThick.png │ │ ├── Normal.png │ │ ├── NormalThick.png │ │ ├── Pressed.png │ │ └── PressedThick.png │ │ ├── SpriteEditView │ │ └── Checkerboard.png │ │ ├── SpritePanel │ │ └── Background_1600.png │ │ ├── TextInput │ │ ├── Disabled.png │ │ ├── Hovered.png │ │ ├── Normal.png │ │ └── Selected.png │ │ ├── Thumbnail │ │ ├── Active.png │ │ ├── Backdrop.png │ │ ├── Hovered.png │ │ └── Selected.png │ │ └── WindowBackground.png │ ├── Linux │ └── README.txt │ └── Windows │ └── README.txt ├── Scripts └── Linux │ ├── FormatEngineSource.sh │ ├── GetRequiredCmake.sh │ ├── InstallDependencies.sh │ ├── InstallLoadTestDependencies.sh │ └── InstallServerDependencies.sh └── Source ├── CMakeLists.txt ├── ClientLib ├── CMakeLists.txt ├── Config │ ├── CMakeLists.txt │ ├── Private │ │ ├── UserConfig.cpp │ │ └── UserConfigInitializer.cpp │ └── Public │ │ ├── UserConfig.h │ │ ├── UserConfig.json │ │ ├── UserConfigInitializer.h │ │ └── UserConfigStructs.h ├── Launch │ ├── CMakeLists.txt │ ├── Private │ │ └── Application.cpp │ └── Public │ │ └── Application.h ├── Network │ ├── CMakeLists.txt │ ├── Private │ │ ├── MessageProcessor.cpp │ │ └── Network.cpp │ └── Public │ │ ├── ConnectionError.h │ │ ├── IMessageProcessorExtension.h │ │ ├── MessageProcessor.h │ │ ├── MessageProcessorExDependencies.h │ │ ├── Network.h │ │ └── PlayerMovementUpdate.h ├── Renderer │ ├── CMakeLists.txt │ ├── Private │ │ ├── Renderer.cpp │ │ └── WorldSpriteSorter.cpp │ └── Public │ │ ├── IRendererExtension.h │ │ ├── Renderer.h │ │ ├── RendererExDependencies.h │ │ ├── SpriteSortInfo.h │ │ └── WorldSpriteSorter.h ├── Simulation │ ├── CMakeLists.txt │ ├── Private │ │ ├── AVSystem.cpp │ │ ├── CameraSystem.cpp │ │ ├── CastHelper.cpp │ │ ├── CastSystem.cpp │ │ ├── ChunkUpdateSystem.cpp │ │ ├── ComponentUpdateSystem.cpp │ │ ├── EntityLifetimeSystem.cpp │ │ ├── GraphicData │ │ │ └── GraphicData.cpp │ │ ├── GraphicSystem.cpp │ │ ├── IconData │ │ │ └── IconData.cpp │ │ ├── InteractionSystem.cpp │ │ ├── InventorySystem.cpp │ │ ├── ItemData │ │ │ └── ItemData.cpp │ │ ├── ItemSystem.cpp │ │ ├── NpcMovementSystem.cpp │ │ ├── PlayerInputSystem.cpp │ │ ├── PlayerMovementSystem.cpp │ │ ├── ReplicationTickOffset.cpp │ │ ├── ServerConnectionSystem.cpp │ │ ├── Simulation.cpp │ │ ├── TileMap │ │ │ └── TileMap.cpp │ │ ├── TileUpdateSystem.cpp │ │ └── World.cpp │ └── Public │ │ ├── AVSystem.h │ │ ├── CameraSystem.h │ │ ├── CastHelper.h │ │ ├── CastSystem.h │ │ ├── CastableData │ │ ├── AVEntityState.h │ │ └── VisualEffectState.h │ │ ├── ChunkUpdateSystem.h │ │ ├── ComponentUpdateSystem.h │ │ ├── Components │ │ ├── AVEffects.h │ │ ├── ClientCastState.h │ │ ├── ClientGraphicState.h │ │ ├── InputHistory.h │ │ └── NeedsAdjacentChunks.h │ │ ├── EntityLifetimeSystem.h │ │ ├── EnttGroups.h │ │ ├── GraphicData │ │ ├── AnimationRenderData.h │ │ ├── GraphicData.h │ │ └── SpriteRenderData.h │ │ ├── GraphicSystem.h │ │ ├── ISimulationExtension.h │ │ ├── IconData │ │ ├── IconData.h │ │ └── IconRenderData.h │ │ ├── InteractionSystem.h │ │ ├── InventorySystem.h │ │ ├── ItemData │ │ ├── ItemCache.h │ │ └── ItemData.h │ │ ├── ItemSystem.h │ │ ├── NpcMovementSystem.h │ │ ├── PlayerInputSystem.h │ │ ├── PlayerMovementSystem.h │ │ ├── ReplicationTickOffset.h │ │ ├── ServerConnectionSystem.h │ │ ├── Simulation.h │ │ ├── SimulationExDependencies.h │ │ ├── TileMap │ │ └── TileMap.h │ │ ├── TileUpdateSystem.h │ │ ├── World.h │ │ └── WorldObjectID.h ├── UserInterface │ ├── CMakeLists.txt │ ├── Private │ │ ├── UserInterface.cpp │ │ └── WorldObjectLocator.cpp │ └── Public │ │ ├── IUserInterfaceExtension.h │ │ ├── PhantomSpriteInfo.h │ │ ├── SpriteColorModInfo.h │ │ ├── UserInterface.h │ │ ├── UserInterfaceExDependencies.h │ │ └── WorldObjectLocator.h └── Utility │ ├── CMakeLists.txt │ ├── Private │ └── ClientTransforms.cpp │ └── Public │ └── ClientTransforms.h ├── EngineSupplementExamples ├── Client │ └── Config │ │ └── Public │ │ └── Config.h ├── README.md ├── Server │ ├── Config │ │ └── Public │ │ │ └── Config.h │ └── Simulation │ │ └── Public │ │ └── TypeLists │ │ ├── ProjectAITypes.h │ │ ├── ProjectObservedComponentTypes.h │ │ └── ProjectPersistedComponentTypes.h └── Shared │ ├── Config │ └── Public │ │ └── SharedConfig.h │ ├── Simulation │ └── Public │ │ ├── EntityGraphicType.h │ │ ├── EntityInteractionType.h │ │ ├── ItemInteractionType.h │ │ └── TypeLists │ │ └── ProjectReplicatedComponentTypes.h │ └── UserInterface │ └── Public │ └── DisplayStrings.h ├── ResourceImporter ├── CMakeLists.txt ├── Config │ ├── CMakeLists.txt │ └── Public │ │ └── Config.h ├── DataModel │ ├── CMakeLists.txt │ ├── Private │ │ ├── AnimationModel.cpp │ │ ├── BoundingBoxModel.cpp │ │ ├── DataModel.cpp │ │ ├── EditorAnimation.cpp │ │ ├── EditorGraphicRef.cpp │ │ ├── EditorSprite.cpp │ │ ├── EntityGraphicSetModel.cpp │ │ ├── GraphicSetModel.cpp │ │ ├── IconModel.cpp │ │ └── SpriteModel.cpp │ └── Public │ │ ├── AnimationModel.h │ │ ├── BoundingBoxModel.h │ │ ├── DataModel.h │ │ ├── EditorAnimation.h │ │ ├── EditorBoundingBox.h │ │ ├── EditorEntityGraphicSet.h │ │ ├── EditorFloorGraphicSet.h │ │ ├── EditorGraphicRef.h │ │ ├── EditorIcon.h │ │ ├── EditorIconSheet.h │ │ ├── EditorObjectGraphicSet.h │ │ ├── EditorSprite.h │ │ ├── EditorSpriteSheet.h │ │ ├── EditorTerrainGraphicSet.h │ │ ├── EditorWallGraphicSet.h │ │ ├── EntityGraphicSetModel.h │ │ ├── GraphicSetModel.h │ │ ├── IconModel.h │ │ ├── LibraryItemData.h │ │ ├── SpriteModel.h │ │ └── SpriteSheetID.h ├── Launch │ ├── CMakeLists.txt │ ├── Private │ │ ├── Application.cpp │ │ └── main.cpp │ └── Public │ │ └── Application.h ├── Renderer │ ├── CMakeLists.txt │ ├── Private │ │ └── Renderer.cpp │ └── Public │ │ └── Renderer.h ├── UserInterface │ ├── CMakeLists.txt │ ├── Private │ │ ├── MainScreen.cpp │ │ ├── TitleScreen.cpp │ │ ├── UserInterface.cpp │ │ ├── Widgets │ │ │ ├── AnimationElementsListItem.cpp │ │ │ ├── AnimationTimeline.cpp │ │ │ ├── BoundingBoxGizmo.cpp │ │ │ ├── GraphicSetSlot.cpp │ │ │ ├── LibraryCollapsibleContainer.cpp │ │ │ ├── LibraryListItem.cpp │ │ │ ├── MainButton.cpp │ │ │ ├── MainTextInput.cpp │ │ │ ├── MainThumbnail.cpp │ │ │ ├── ParentListItem.cpp │ │ │ ├── PointGizmo.cpp │ │ │ ├── StageGraphic.cpp │ │ │ ├── TimelineFrame.cpp │ │ │ ├── TimelineScrubber.cpp │ │ │ └── TitleButton.cpp │ │ └── Windows │ │ │ ├── AddIconSheetDialog.cpp │ │ │ ├── AddSpriteDialog.cpp │ │ │ ├── AnimationEditView.cpp │ │ │ ├── AnimationElementsWindow.cpp │ │ │ ├── AnimationPropertiesWindow.cpp │ │ │ ├── BoundingBoxEditView.cpp │ │ │ ├── BoundingBoxPropertiesWindow.cpp │ │ │ ├── EntityGraphicSetEditView.cpp │ │ │ ├── EntityGraphicSetPropertiesWindow.cpp │ │ │ ├── GraphicSetEditView.cpp │ │ │ ├── GraphicSetPropertiesWindow.cpp │ │ │ ├── HamburgerButtonWindow.cpp │ │ │ ├── HamburgerMenu.cpp │ │ │ ├── IconEditView.cpp │ │ │ ├── IconPropertiesWindow.cpp │ │ │ ├── LibraryAddMenu.cpp │ │ │ ├── LibraryWindow.cpp │ │ │ ├── SaveBoundingBoxDialog.cpp │ │ │ ├── SpriteEditView.cpp │ │ │ ├── SpritePropertiesWindow.cpp │ │ │ ├── SpriteSheetEditView.cpp │ │ │ ├── SpriteSheetPropertiesWindow.cpp │ │ │ └── TitleWindow.cpp │ └── Public │ │ ├── MainScreen.h │ │ ├── TitleScreen.h │ │ ├── UserInterface.h │ │ ├── Widgets │ │ ├── AnimationElementsListItem.h │ │ ├── AnimationTimeline.h │ │ ├── BoundingBoxGizmo.h │ │ ├── GraphicSetSlot.h │ │ ├── LibraryCollapsibleContainer.h │ │ ├── LibraryListItem.h │ │ ├── MainButton.h │ │ ├── MainTextInput.h │ │ ├── MainThumbnail.h │ │ ├── ParentListItem.h │ │ ├── PointGizmo.h │ │ ├── StageGraphic.h │ │ ├── TimelineFrame.h │ │ ├── TimelineScrubber.h │ │ └── TitleButton.h │ │ └── Windows │ │ ├── AddIconSheetDialog.h │ │ ├── AddSpriteDialog.h │ │ ├── AnimationEditView.h │ │ ├── AnimationElementsWindow.h │ │ ├── AnimationPropertiesWindow.h │ │ ├── BoundingBoxEditView.h │ │ ├── BoundingBoxPropertiesWindow.h │ │ ├── EntityGraphicSetEditView.h │ │ ├── EntityGraphicSetPropertiesWindow.h │ │ ├── GraphicSetEditView.h │ │ ├── GraphicSetPropertiesWindow.h │ │ ├── HamburgerButtonWindow.h │ │ ├── HamburgerMenu.h │ │ ├── IconEditView.h │ │ ├── IconPropertiesWindow.h │ │ ├── LibraryAddMenu.h │ │ ├── LibraryWindow.h │ │ ├── SaveBoundingBoxDialog.h │ │ ├── SpriteEditView.h │ │ ├── SpritePropertiesWindow.h │ │ ├── SpriteSheetEditView.h │ │ ├── SpriteSheetPropertiesWindow.h │ │ └── TitleWindow.h └── Utility │ ├── CMakeLists.txt │ ├── Private │ └── SpriteTools.cpp │ └── Public │ └── SpriteTools.h ├── ServerLib ├── CMakeLists.txt ├── Config │ ├── CMakeLists.txt │ ├── Private │ │ ├── UserConfig.cpp │ │ └── UserConfigInitializer.cpp │ └── Public │ │ ├── UserConfig.h │ │ └── UserConfigInitializer.h ├── Launch │ ├── CMakeLists.txt │ ├── Private │ │ └── Application.cpp │ └── Public │ │ └── Application.h ├── Network │ ├── CMakeLists.txt │ ├── Private │ │ ├── Client.cpp │ │ ├── ClientHandler.cpp │ │ ├── MessageProcessor.cpp │ │ ├── Network.cpp │ │ └── SDLNetInitializer.cpp │ └── Public │ │ ├── Client.h │ │ ├── ClientConnectionEvent.h │ │ ├── ClientHandler.h │ │ ├── ClientMap.h │ │ ├── IMessageProcessorExtension.h │ │ ├── MessageProcessor.h │ │ ├── MessageProcessorExDependencies.h │ │ ├── Network.h │ │ └── SDLNetInitializer.h └── Simulation │ ├── CMakeLists.txt │ ├── Private │ ├── AISystem.cpp │ ├── CastHelper.cpp │ ├── CastSystem.cpp │ ├── ChunkStreamingSystem.cpp │ ├── ClientAOISystem.cpp │ ├── ClientConnectionSystem.cpp │ ├── ComponentChangeSystem.cpp │ ├── ComponentSyncSystem.cpp │ ├── Components │ │ └── StoredValues.cpp │ ├── Database.cpp │ ├── DialogueSystem.cpp │ ├── GraphicData │ │ └── GraphicData.cpp │ ├── IconData │ │ └── IconData.cpp │ ├── InputSystem.cpp │ ├── InventoryHelpers.cpp │ ├── InventorySystem.cpp │ ├── ItemData │ │ └── ItemData.cpp │ ├── ItemSystem.cpp │ ├── Lua │ │ └── EngineLuaBindings.cpp │ ├── MovementSyncSystem.cpp │ ├── MovementSystem.cpp │ ├── NceLifetimeSystem.cpp │ ├── SaveSystem.cpp │ ├── ScriptDataSystem.cpp │ ├── Simulation.cpp │ ├── TileMap │ │ └── TileMap.cpp │ ├── TileUpdateSystem.cpp │ └── World.cpp │ └── Public │ ├── AILogic.h │ ├── AISystem.h │ ├── CastHelper.h │ ├── CastSystem.h │ ├── ChunkStreamingSystem.h │ ├── ClientAOISystem.h │ ├── ClientConnectionSystem.h │ ├── ComponentChangeSystem.h │ ├── ComponentSyncSystem.h │ ├── Components │ ├── CastState.h │ ├── ClientSimData.h │ ├── Dialogue.h │ ├── ItemHandlers.h │ ├── ReplicatedComponentList.h │ └── StoredValues.h │ ├── Database.h │ ├── DialogueSystem.h │ ├── EntityItemHandlerScript.h │ ├── EntityStoredValueID.h │ ├── EntityStoredValueIDMap.h │ ├── EnttGroups.h │ ├── EventSorter.h │ ├── GlobalStoredValueMap.h │ ├── GraphicData │ └── GraphicData.h │ ├── ISimulationExtension.h │ ├── IconData │ └── IconData.h │ ├── InputSystem.h │ ├── InventoryHelpers.h │ ├── InventorySystem.h │ ├── ItemData │ └── ItemData.h │ ├── ItemSystem.h │ ├── Lua │ ├── DialogueChoiceConditionLua.h │ ├── DialogueLua.h │ ├── EngineLuaBindings.h │ ├── EntityInitLua.h │ ├── EntityItemHandlerLua.h │ └── ItemInitLua.h │ ├── MovementSyncSystem.h │ ├── MovementSystem.h │ ├── NceLifetimeSystem.h │ ├── SaveSystem.h │ ├── ScriptDataSystem.h │ ├── Simulation.h │ ├── SimulationExDependencies.h │ ├── SpawnStrategy.h │ ├── TileMap │ └── TileMap.h │ ├── TileUpdateSystem.h │ ├── TypeLists │ ├── EngineObservedComponentTypes.h │ └── EnginePersistedComponentTypes.h │ └── World.h ├── SharedLib ├── CMakeLists.txt ├── Messages │ ├── CMakeLists.txt │ └── Public │ │ ├── CastCooldownInit.h │ │ ├── CastFailed.h │ │ ├── CastRequest.h │ │ ├── CastStarted.h │ │ ├── ChunkDataRequest.h │ │ ├── ChunkUpdate.h │ │ ├── ChunkWireSnapshot.h │ │ ├── CombineItems.h │ │ ├── CombineItemsRequest.h │ │ ├── ComponentUpdate.h │ │ ├── ConnectionRequest.h │ │ ├── ConnectionResponse.h │ │ ├── DialogueChoiceRequest.h │ │ ├── DialogueResponse.h │ │ ├── EngineMessageType.h │ │ ├── EntityDelete.h │ │ ├── EntityDeleteRequest.h │ │ ├── EntityInit.h │ │ ├── EntityInitRequest.h │ │ ├── EntityInitScriptRequest.h │ │ ├── EntityInitScriptResponse.h │ │ ├── EntityNameChangeRequest.h │ │ ├── ExplicitConfirmation.h │ │ ├── GraphicStateChangeRequest.h │ │ ├── Heartbeat.h │ │ ├── InputChangeRequest.h │ │ ├── InventoryAddItem.h │ │ ├── InventoryInit.h │ │ ├── InventoryMoveItem.h │ │ ├── InventoryOperation.h │ │ ├── InventoryRemoveItem.h │ │ ├── ItemChangeRequest.h │ │ ├── ItemDataRequest.h │ │ ├── ItemError.h │ │ ├── ItemInitRequest.h │ │ ├── ItemInitScriptRequest.h │ │ ├── ItemInitScriptResponse.h │ │ ├── ItemUpdate.h │ │ ├── MovementState.h │ │ ├── MovementUpdate.h │ │ ├── SystemMessage.h │ │ ├── TileAddLayer.h │ │ ├── TileClearLayers.h │ │ ├── TileExtentClearLayers.h │ │ ├── TileRemoveLayer.h │ │ └── UseItemOnEntityRequest.h ├── Network │ ├── CMakeLists.txt │ ├── Private │ │ ├── Acceptor.cpp │ │ ├── NetworkStats.cpp │ │ ├── Peer.cpp │ │ ├── SocketSet.cpp │ │ └── TcpSocket.cpp │ └── Public │ │ ├── Acceptor.h │ │ ├── DispatchMessage.h │ │ ├── NetworkDefs.h │ │ ├── NetworkID.h │ │ ├── NetworkStats.h │ │ ├── Peer.h │ │ ├── SocketSet.h │ │ └── TcpSocket.h ├── Simulation │ ├── CMakeLists.txt │ ├── Private │ │ ├── BoundingBox.cpp │ │ ├── CastableData │ │ │ ├── Castable.cpp │ │ │ └── CastableData.cpp │ │ ├── CollisionLocator.cpp │ │ ├── Components │ │ │ ├── Camera.cpp │ │ │ ├── CastCooldown.cpp │ │ │ ├── Interaction.cpp │ │ │ └── Inventory.cpp │ │ ├── Cylinder.cpp │ │ ├── EntityLocator.cpp │ │ ├── EntityMover.cpp │ │ ├── GraphicData │ │ │ ├── Animation.cpp │ │ │ ├── GraphicDataBase.cpp │ │ │ ├── GraphicID.cpp │ │ │ ├── GraphicRef.cpp │ │ │ └── GraphicSets.cpp │ │ ├── IconData │ │ │ └── IconDataBase.cpp │ │ ├── ItemData │ │ │ ├── Item.cpp │ │ │ └── ItemDataBase.cpp │ │ ├── MovementHelpers.cpp │ │ ├── Ray.cpp │ │ ├── ResourceData.cpp │ │ ├── TileMap │ │ │ ├── CellExtent.cpp │ │ │ ├── CellPosition.cpp │ │ │ ├── Chunk.cpp │ │ │ ├── ChunkExtent.cpp │ │ │ ├── ChunkPosition.cpp │ │ │ ├── Floor.cpp │ │ │ ├── Terrain.cpp │ │ │ ├── Tile.cpp │ │ │ ├── TileExtent.cpp │ │ │ ├── TileLayer.cpp │ │ │ ├── TileMapBase.cpp │ │ │ └── TilePosition.cpp │ │ └── Vector3.cpp │ └── Public │ │ ├── BoundingBox.h │ │ ├── BoundingBoxID.h │ │ ├── CastableData │ │ ├── AVEntity.h │ │ ├── CastFailureType.h │ │ ├── CastInfo.h │ │ ├── Castable.h │ │ ├── CastableData.h │ │ ├── CastableID.h │ │ ├── EngineCastableDef.h │ │ └── VisualEffect.h │ │ ├── CollisionLocator.h │ │ ├── Components │ │ ├── Camera.h │ │ ├── CastCooldown.h │ │ ├── Collision.h │ │ ├── EntityInitScript.h │ │ ├── GraphicState.h │ │ ├── Input.h │ │ ├── Interaction.h │ │ ├── Inventory.h │ │ ├── IsClientEntity.h │ │ ├── Movement.h │ │ ├── MovementModifiers.h │ │ ├── Name.h │ │ ├── Position.h │ │ ├── PreviousPosition.h │ │ ├── Rotation.h │ │ └── SaveTimestamp.h │ │ ├── Cylinder.h │ │ ├── DialogueEvent.h │ │ ├── DiscreteExtent.h │ │ ├── DiscreteImpl.h │ │ ├── DiscretePosition.h │ │ ├── EngineEntityGraphicType.h │ │ ├── EngineEntityInteractionType.h │ │ ├── EngineItemInteractionType.h │ │ ├── EntityLocator.h │ │ ├── EntityMover.h │ │ ├── EnttObserver.h │ │ ├── GraphicData │ │ ├── Animation.h │ │ ├── AnimationID.h │ │ ├── GraphicDataBase.h │ │ ├── GraphicID.h │ │ ├── GraphicRef.h │ │ ├── GraphicSetIDs.h │ │ ├── GraphicSets.h │ │ ├── Sprite.h │ │ └── SpriteID.h │ │ ├── IconData │ │ ├── Icon.h │ │ ├── IconDataBase.h │ │ └── IconID.h │ │ ├── ItemData │ │ ├── Item.h │ │ ├── ItemCombination.h │ │ ├── ItemDataBase.h │ │ ├── ItemID.h │ │ ├── ItemInitScript.h │ │ └── ItemProperty.h │ │ ├── MovementHelpers.h │ │ ├── Ray.h │ │ ├── ReplicatedComponent.h │ │ ├── ResourceData.h │ │ ├── TileMap │ │ ├── CellExtent.h │ │ ├── CellPosition.h │ │ ├── Chunk.h │ │ ├── ChunkExtent.h │ │ ├── ChunkPosition.h │ │ ├── ChunkSnapshot.h │ │ ├── Floor.h │ │ ├── Terrain.h │ │ ├── Tile.h │ │ ├── TileExtent.h │ │ ├── TileLayer.h │ │ ├── TileLayerID.h │ │ ├── TileMapBase.h │ │ ├── TileMapSnapshot.h │ │ ├── TileOffset.h │ │ ├── TilePosition.h │ │ └── Wall.h │ │ ├── TypeLists │ │ └── EngineReplicatedComponentTypes.h │ │ └── Vector3.h └── Utility │ ├── CMakeLists.txt │ ├── Private │ ├── AssetCache.cpp │ ├── ByteTools.cpp │ ├── IDPool.cpp │ ├── Log.cpp │ ├── Morton.cpp │ ├── Paths.cpp │ ├── PeriodicCaller.cpp │ ├── SDLHelpers.cpp │ ├── StringTools.cpp │ ├── Timer.cpp │ ├── Transforms.cpp │ └── pch.h │ └── Public │ ├── AMAssert.h │ ├── AssetCache.h │ ├── BinaryBuffer.h │ ├── ByteTools.h │ ├── ConstexprTools.h │ ├── Deserialize.h │ ├── HashTools.h │ ├── IDPool.h │ ├── Log.h │ ├── Morton.h │ ├── OSEventHandler.h │ ├── Paths.h │ ├── PeriodicCaller.h │ ├── SDLHelpers.h │ ├── Serialize.h │ ├── SerializeBuffer.h │ ├── StringTools.h │ ├── Timer.h │ ├── Transforms.h │ └── VariantTools.h ├── Tests ├── CMakeLists.txt ├── TestSandboxes │ ├── CMakeLists.txt │ ├── Graphics │ │ ├── CMakeLists.txt │ │ └── Private │ │ │ └── FrameTimeTestMain.cpp │ └── Network │ │ ├── CMakeLists.txt │ │ ├── ClockTest │ │ ├── CMakeLists.txt │ │ └── Private │ │ │ ├── ClockTestClientMain.cpp │ │ │ └── ClockTestServerMain.cpp │ │ ├── DriftTest │ │ ├── CMakeLists.txt │ │ └── Private │ │ │ ├── DriftTestClientMain.cpp │ │ │ └── DriftTestServerMain.cpp │ │ ├── LatencyTest │ │ ├── CMakeLists.txt │ │ └── Private │ │ │ ├── LatencyTestClientMain.cpp │ │ │ └── LatencyTestServerMain.cpp │ │ └── LoadTest │ │ ├── CMakeLists.txt │ │ ├── Private │ │ ├── LoadTestClientMain.cpp │ │ ├── NetworkSimulation.cpp │ │ ├── SimulatedClient.cpp │ │ └── WorldSimulation.cpp │ │ └── Public │ │ ├── NetworkSimulation.h │ │ ├── SimulatedClient.h │ │ └── WorldSimulation.h └── UnitTests │ ├── CMakeLists.txt │ └── Private │ ├── TestBoundingBox.cpp │ ├── TestEntityLocator.cpp │ └── TestMain.cpp └── Tools ├── CMakeLists.txt └── EngineDatabaseMigrator ├── CMakeLists.txt └── Private ├── EngineDatabaseMigratorMain.cpp ├── MigrateEngineComponents.cpp ├── MigrateEngineComponents.h ├── MigrationRunner.cpp └── MigrationRunner.h /.gitattributes: -------------------------------------------------------------------------------- 1 | *.dll filter=lfs diff=lfs merge=lfs -text 2 | *.so.* filter=lfs diff=lfs merge=lfs -text 3 | *.png filter=lfs diff=lfs merge=lfs -text 4 | *.bmp filter=lfs diff=lfs merge=lfs -text 5 | *.ttf filter=lfs diff=lfs merge=lfs -text 6 | *.bin filter=lfs diff=lfs merge=lfs -text 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Binaries/ 2 | .settings/ 3 | /Build/ 4 | *.tar.gz 5 | /Output/ 6 | *.log 7 | *.swp 8 | .vs/ 9 | SystemPATHBackup.txt 10 | 11 | # MacOS junk files 12 | .DS_Store 13 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Amalgam 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /CMake/AddressSanitizer.cmake: -------------------------------------------------------------------------------- 1 | # Support for building with AddressSanitizer (ASan) - 2 | # https://code.google.com/p/address-sanitizer/ 3 | # 4 | # Note: Including this file enables ASan for all targets in the current 5 | # directory and all sub-directories (that are added after including 6 | # this file). 7 | 8 | INCLUDE(CheckCCompilerFlag) 9 | INCLUDE(CheckCXXCompilerFlag) 10 | INCLUDE(CMakePushCheckState) 11 | 12 | CMAKE_PUSH_CHECK_STATE(RESET) 13 | SET(CMAKE_REQUIRED_FLAGS "-fsanitize=address") # Also needs to be a link flag for test to pass 14 | CHECK_C_COMPILER_FLAG("-fsanitize=address" HAVE_FLAG_SANITIZE_ADDRESS_C) 15 | CHECK_CXX_COMPILER_FLAG("-fsanitize=address" HAVE_FLAG_SANITIZE_ADDRESS_CXX) 16 | CMAKE_POP_CHECK_STATE() 17 | 18 | IF(HAVE_FLAG_SANITIZE_ADDRESS_C AND HAVE_FLAG_SANITIZE_ADDRESS_CXX) 19 | SET(ADDRESS_SANITIZER_FLAG "-fsanitize=address") 20 | 21 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ADDRESS_SANITIZER_FLAG}") 22 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ADDRESS_SANITIZER_FLAG}") 23 | SET(CMAKE_CGO_LDFLAGS "${CMAKE_CGO_LDFLAGS} ${ADDRESS_SANITIZER_FLAG}") 24 | 25 | ADD_DEFINITIONS(-DADDRESS_SANITIZER) 26 | 27 | MESSAGE(STATUS "AM: AddressSanitizer enabled.") 28 | ELSE() 29 | MESSAGE(FATAL_ERROR "AM_ADDRESSSANITIZER enabled but compiler doesn't support AddressSanitizer - cannot continue.") 30 | ENDIF() 31 | -------------------------------------------------------------------------------- /CMake/SDL2_net.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | message(STATUS "Configuring SDL_net") 4 | 5 | # Add our static library target 6 | add_library(SDL2_net-static STATIC 7 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net/SDLnet.c 8 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net/SDLnetTCP.c 9 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net/SDLnetUDP.c 10 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net/SDLnetselect.c 11 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net/SDLnetsys.h 12 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net/SDL_net.h 13 | ) 14 | set_target_properties(SDL2_net-static PROPERTIES OUTPUT_NAME "SDL2_net") 15 | 16 | target_include_directories(SDL2_net-static 17 | PRIVATE 18 | ${SDL2_INCLUDE_DIRS} 19 | PUBLIC 20 | ${PROJECT_SOURCE_DIR}/Libraries/SDL_net 21 | ) 22 | 23 | target_link_libraries(SDL2_net-static PRIVATE ${SDL2_LIBRARIES}) 24 | 25 | if(MINGW OR MSVC) 26 | target_link_libraries(SDL2_net-static PRIVATE ws2_32 iphlpapi) 27 | endif() 28 | 29 | # Disable Nagle's algorithm. 30 | target_compile_options(SDL2_net-static PRIVATE -DTCP_NODELAY) 31 | -------------------------------------------------------------------------------- /CMake/ThreadSanitizer.cmake: -------------------------------------------------------------------------------- 1 | # Support for building with ThreadSanitizer (TSan) - 2 | # https://code.google.com/p/thread-sanitizer/ 3 | # 4 | # Copied from ForestDB under the Apache-2.0 License. 5 | # https://github.com/couchbase/forestdb 6 | # 7 | # Note: Including this file enables TSan for all targets in the current 8 | # directory and all sub-directories (that are added after including 9 | # this file). 10 | 11 | INCLUDE(CheckCCompilerFlag) 12 | INCLUDE(CheckCXXCompilerFlag) 13 | INCLUDE(CMakePushCheckState) 14 | 15 | CMAKE_PUSH_CHECK_STATE(RESET) 16 | SET(CMAKE_REQUIRED_FLAGS "-fsanitize=thread") # Also needs to be a link flag for test to pass 17 | CHECK_C_COMPILER_FLAG("-fsanitize=thread" HAVE_FLAG_SANITIZE_THREAD_C) 18 | CHECK_CXX_COMPILER_FLAG("-fsanitize=thread" HAVE_FLAG_SANITIZE_THREAD_CXX) 19 | CMAKE_POP_CHECK_STATE() 20 | 21 | IF(HAVE_FLAG_SANITIZE_THREAD_C AND HAVE_FLAG_SANITIZE_THREAD_CXX) 22 | SET(THREAD_SANITIZER_FLAG "-fsanitize=thread") 23 | 24 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${THREAD_SANITIZER_FLAG}") 25 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${THREAD_SANITIZER_FLAG}") 26 | SET(CMAKE_CGO_LDFLAGS "${CMAKE_CGO_LDFLAGS} ${THREAD_SANITIZER_FLAG}") 27 | 28 | ADD_DEFINITIONS(-DTHREAD_SANITIZER) 29 | 30 | MESSAGE(STATUS "AM: ThreadSanitizer enabled.") 31 | ELSE() 32 | MESSAGE(FATAL_ERROR "AM_THREADSANITIZER enabled but compiler doesn't support ThreadSanitizer - cannot continue.") 33 | ENDIF() 34 | -------------------------------------------------------------------------------- /CMake/readerwriterqueue.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | # Add our header-only library target 4 | add_library(readerwriterqueue INTERFACE) 5 | 6 | target_include_directories(readerwriterqueue 7 | INTERFACE 8 | ${PROJECT_SOURCE_DIR}/Libraries/readerwriterqueue/ 9 | ) 10 | 11 | target_sources(readerwriterqueue INTERFACE 12 | ${PROJECT_SOURCE_DIR}/Libraries/readerwriterqueue/readerwriterqueue.h 13 | ${PROJECT_SOURCE_DIR}/Libraries/readerwriterqueue/atomicops.h 14 | ) 15 | -------------------------------------------------------------------------------- /Resources/EngineDefaults/Common/Assets/Textures/Defaults/Icon.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f64ba7b0f3f8135b459a921738fc40b0788dafb3978a360a24d01cbcc06bc6a1 3 | size 574 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Fonts/B612-Regular.ttf: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:77302b6dd7603574ecb35fca7bf79df449b3c46757afd19d6e482f6f80a26ed0 3 | size 142728 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Checkbox/Checked.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a3a04c0d9a9cfd2b1270de9fd5129edeb25c87622bf1d59fe99873efe54b806d 3 | size 175 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Checkbox/Unchecked.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:06f0866eb6cc6aa85539ab078c6ae53d6370685e6d71717e0b62b4d896fa52d2 3 | size 169 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Dialogs/Shadow.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c83f3e6fcd788d1bf5c2d6e21dac72fc2d1c841d431e6f0916b0b6eaf0b4c4ea 3 | size 212 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/HamburgerButton/Hovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8867987dc7b66e03bc92c4f3ca6c0d37f600788191f8cabc78b27a722c7627d4 3 | size 179 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/HamburgerButton/Normal.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a497200e87bb6c4c4623442151ae6d9c4fa21a5cc919c859ce3ca3c56c4c0b1a 3 | size 173 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/HamburgerButton/Pressed.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c15857c3477847b956b71f055574221910dc6525dec1d129eb284e8812ec7350 3 | size 179 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/HeaderBackground.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d96944e5f1caf71b79825f58fe71a7260679ef4aac9e110b8a7d53b4900fafb9 3 | size 172 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Highlights/Hovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5d45c5c41184a27e2077f68056327b6c92541a10c06c3be89ca34c52b432d094 3 | size 153 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Highlights/Selected.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e7018339a92fda153dc3b8dbef4f8312d269d58cfe94500032efa9f6d084681c 3 | size 153 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/Collapsed_1600.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cce9a8664c758f4db8297bdfa3c22fb63ebabe537692ff86fe337e6859c4c6ce 3 | size 294 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/Collapsed_1920.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5b53d396eea3296b9ec278e12445c8ac34311cd123bc3b9526e14a056159098a 3 | size 277 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/Expanded_1600.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aee9b53e2060b77b95e7ec681938baa31c823eb8445da168ee813f1fdf245c84 3 | size 285 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/Expanded_1920.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9ae6caf3e2656858203d1f51cc8df4c39a11e2a57213e4cc5318f1ae368a00c8 3 | size 265 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/Minus.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:360840092db844c2b9b5579c4d4471f0a6a786669db26d70b2f8dce21af406ca 3 | size 155 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/MinusHovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:707d8f3d5ba183ed23af8742b9528c8397c4d1b4dbfeb693003b74c4ee511d81 3 | size 157 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/Plus.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:396f0138d525a6c9ebec9b89e530f8a3d34c30115e1fdad2c7221592256f4d77 3 | size 206 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Icons/PlusHovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:27210eae1b90b5dfd11286a7193ea25db4b290fb9cbecdf4c6520c6561a77b18 3 | size 214 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/Disabled.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8b8932d271eb736704e89256bf970ae3125c02962a0962ee6cdefdf13d44de2e 3 | size 191 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/DisabledThick.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a73376efaf8596c331be1d6ba916db509d39650a6ddd2d98a08437864bba2403 3 | size 209 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/Hovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7db8b078df690f11eecd7d409212d4c1e06985de468c72ad4b66c1f26bad6da4 3 | size 193 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/HoveredThick.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9e58630131a9bcfb4e712309c1e7c0282c8de7f1198acc6616e48c03e07b67f1 3 | size 211 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/Normal.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8fd4f2722c4891de0ba57e41a1cce7159aaa9035fd49113559b6e4888e3c07b3 3 | size 193 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/NormalThick.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c625ada5dcc9e201b64ccc2ded6229d4d55fd529c831e214ba69487be45cd404 3 | size 211 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/Pressed.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3128a450508a9ecb1f576bba90f523572597a4b1044463b540f4fd0973359193 3 | size 179 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/MainButton/PressedThick.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:18da5edcf8e77a8dc3be60e5727b2ba631114ec2be98c1378efae2d62dfdbf74 3 | size 190 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/SpriteEditView/Checkerboard.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a5fd64e2f76d44518acb33ea59b618b0560d48c1061074c6cb8db48b61f32908 3 | size 237 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/SpritePanel/Background_1600.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:40bf41e5b7f1a93880718bd6cb09dc94e1bcea094105ffa9a47b71372e9af797 3 | size 24452 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/TextInput/Disabled.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b42f7ff1483ec71dcd180688d0db3823f781b0b277fcd7e44e4466fa7633714d 3 | size 499 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/TextInput/Hovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:090418165cd017e561def136dc6bef2c4e9d54e81a77823f528a9413da41dfaf 3 | size 498 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/TextInput/Normal.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:02ecd6c86ef7f1f9e11fa3e8899a9f6d90e34f7461edf2674d7a0283710b549b 3 | size 498 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/TextInput/Selected.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b35a732ea29a4e7aa86c3cdab60321e47314ad3c9dba807baea3ecb821f99e2a 3 | size 540 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Thumbnail/Active.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8cd392193d403b550ee18cef4ed663d22afbdecf35aea012995ee88b43c24a5b 3 | size 492 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Thumbnail/Backdrop.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:49d1638c04c6c5e447632e8745dda729bfd868fa19592e593c7568d9890b55e9 3 | size 2936 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Thumbnail/Hovered.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:15443100935e4371eb7c4f28f05667b60ef9b3866768f7321c9bc564bcd7ba19 3 | size 493 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/Thumbnail/Selected.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e980e6160a8f6829fd83c2f1679936f399822970d8924ce04e62c3064fa40288 3 | size 535 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Common/Assets/Textures/WindowBackground.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4cbf479c1d1caeb5abb5526a5b79c6871607f4bd5677f0307c121682f8ec5c10 3 | size 172 4 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Linux/README.txt: -------------------------------------------------------------------------------- 1 | Hello! Thanks for downloading. I hope you enjoy. 2 | - Net_ 3 | 4 | ################### 5 | ## Installation 6 | ################### 7 | No installation is required, just run the application. 8 | 9 | If you have issues, please make sure that you have SDL2 installed. 10 | For Ubuntu: sudo apt install libsdl2-2.0-0 libsdl2-image-2.0-0 libsdl2-mixer-2.0-0 libsdl2-ttf-2.0-0 libsdl2-gfx-1.0-0 11 | -------------------------------------------------------------------------------- /Resources/ResourceImporter/Windows/README.txt: -------------------------------------------------------------------------------- 1 | Hello! Thanks for downloading. I hope you enjoy. 2 | - Net_ 3 | 4 | ################### 5 | ## Installation 6 | ################### 7 | No installation is required, just run the .exe file. 8 | 9 | If you have issues, please make sure that you have the latest Visual C++ Redistributable: 10 | Direct link 11 | https://aka.ms/vs/17/release/vc_redist.x64.exe 12 | Microsoft support page 13 | https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170 14 | -------------------------------------------------------------------------------- /Scripts/Linux/FormatEngineSource.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | REQUIRED_PKG="clang-format" 4 | PKG_OK=$(dpkg-query -W --showformat='${Status}\n' $REQUIRED_PKG|grep "install ok installed") 5 | if [ "" = "$PKG_OK" ]; then 6 | echo "$REQUIRED_PKG not found. Installing." 7 | sudo apt --yes install $REQUIRED_PKG 8 | fi 9 | 10 | # Grab the full path to the base of the repo (assuming this script is in Scripts/Linux) 11 | BasePath="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." >/dev/null 2>&1 && pwd )" 12 | 13 | echo "Running clang-format on engine source code." 14 | find $BasePath/Source -iname '*.h' -o -iname '*.cpp' | xargs clang-format -i 15 | echo "Done." 16 | 17 | -------------------------------------------------------------------------------- /Scripts/Linux/GetRequiredCmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script builds a new enough cmake from source to use for this project. 4 | # If your OS version is new enough, you won't need to use this. 5 | 6 | version=3.24.3 7 | 8 | sudo apt install build-essential libssl-dev 9 | sudo apt purge --auto-remove cmake 10 | 11 | mkdir temp 12 | cd temp 13 | 14 | wget https://github.com/Kitware/CMake/releases/download/v$version/cmake-$version.tar.gz --no-check-certificate 15 | 16 | tar -xzvf cmake-$version.tar.gz 17 | 18 | cd CMake-$version 19 | 20 | # Build and install 21 | ./bootstrap 22 | make -j$(nproc) 23 | sudo make install 24 | 25 | cd ../.. 26 | rm -r temp 27 | 28 | -------------------------------------------------------------------------------- /Scripts/Linux/InstallDependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Installs the dependencies required to do an engine build. 4 | # Tested on 20.04, 24.04. 5 | 6 | sudo apt update 7 | 8 | sudo apt install g++ cmake libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev libsdl2-gfx-dev libgtk-3-dev ninja-build 9 | -------------------------------------------------------------------------------- /Scripts/Linux/InstallLoadTestDependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Installs the dependencies required to run an Amalgam Engine Server application. 4 | # Tested on 24.04. 5 | 6 | sudo apt update 7 | 8 | sudo apt install libsdl2-2.0-0 9 | -------------------------------------------------------------------------------- /Scripts/Linux/InstallServerDependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Installs the dependencies required to run an Amalgam Engine Server application. 4 | # Tested on 24.04. 5 | 6 | sudo apt update 7 | 8 | sudo apt install libsdl2-2.0-0 9 | -------------------------------------------------------------------------------- /Source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | ############################################################################### 4 | # Modules 5 | ############################################################################### 6 | # Configure Shared library. 7 | add_subdirectory(SharedLib) 8 | 9 | # Configure Client library. 10 | add_subdirectory(ClientLib) 11 | 12 | # Configure Server library. 13 | add_subdirectory(ServerLib) 14 | 15 | # Configure Resource Importer. 16 | if (AM_BUILD_RESOURCE_IMPORTER) 17 | add_subdirectory(ResourceImporter) 18 | endif() 19 | 20 | # Configure Tools. 21 | if (AM_BUILD_TOOLS) 22 | add_subdirectory(Tools) 23 | endif() 24 | 25 | # Configure tests. 26 | if (AM_BUILD_TESTS) 27 | add_subdirectory(Tests) 28 | endif() 29 | -------------------------------------------------------------------------------- /Source/ClientLib/Config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ClientLib 2 | PRIVATE 3 | Private/UserConfig.cpp 4 | Private/UserConfigInitializer.cpp 5 | PUBLIC 6 | Public/UserConfig.h 7 | Public/UserConfigInitializer.h 8 | Public/UserConfigStructs.h 9 | ) 10 | 11 | target_include_directories(ClientLib 12 | PRIVATE 13 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 14 | PUBLIC 15 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 16 | ) 17 | -------------------------------------------------------------------------------- /Source/ClientLib/Config/Private/UserConfigInitializer.cpp: -------------------------------------------------------------------------------- 1 | #include "UserConfigInitializer.h" 2 | #include "UserConfig.h" 3 | 4 | namespace AM 5 | { 6 | namespace Client 7 | { 8 | UserConfigInitializer::UserConfigInitializer() 9 | { 10 | UserConfig::get(); 11 | } 12 | 13 | } // End namespace Client 14 | } // End namespace AM 15 | -------------------------------------------------------------------------------- /Source/ClientLib/Config/Public/UserConfig.json: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an example UserConfig.json file, these values are not actually used. 3 | * Projects can reference this file to understand what fields they must 4 | * provide in their UserConfig.json. 5 | */ 6 | 7 | { 8 | // Sets full screen preference. 9 | // 0 = Windowed 10 | // 1 = Borderless windowed 11 | "fullscreenMode": 0, 12 | 13 | // The size of the application window. 14 | // Note: We currently only support 16:9 aspect ratios. 15 | // Note: If fullscreenMode is Fullscreen or Fullscreen windowed, 16 | // this setting is ignored and the desktop size is used. 17 | "windowSizeWidth": 1600, 18 | "windowSizeHeight": 900, 19 | 20 | // The application framerate. 21 | "framesPerSecond": 60, 22 | 23 | // The IP address and port of the simulation server. 24 | "serverIP": "104.237.139.17", 25 | // "serverIP": "127.0.0.1", 26 | "serverPort": 41499 27 | } 28 | -------------------------------------------------------------------------------- /Source/ClientLib/Config/Public/UserConfigInitializer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Client 6 | { 7 | /** 8 | * Minimal helper class to facilitate calling UserConfig::get() from an 9 | * initializer list. 10 | * 11 | * UserConfig::get() must first be called after SDL is initialized, but before 12 | * any threads are spun up that may cause race conditions around UserConfig 13 | * member access. 14 | */ 15 | class UserConfigInitializer 16 | { 17 | public: 18 | UserConfigInitializer(); 19 | }; 20 | 21 | } // End namespace Client 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/ClientLib/Config/Public/UserConfigStructs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /** 6 | * This file contains structs used in UserConfig.h to combine related 7 | * config fields. 8 | */ 9 | namespace AM 10 | { 11 | namespace Client 12 | { 13 | 14 | struct ServerAddress { 15 | std::string IP{}; 16 | 17 | unsigned int port{}; 18 | }; 19 | 20 | } // End namespace Client 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/ClientLib/Launch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ClientLib 2 | PRIVATE 3 | Private/Application.cpp 4 | PUBLIC 5 | Public/Application.h 6 | ) 7 | 8 | target_include_directories(ClientLib 9 | PRIVATE 10 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 11 | PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 13 | ) 14 | -------------------------------------------------------------------------------- /Source/ClientLib/Network/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ClientLib 2 | PRIVATE 3 | Private/Network.cpp 4 | Private/MessageProcessor.cpp 5 | PUBLIC 6 | Public/ConnectionError.h 7 | Public/IMessageProcessorExtension.h 8 | Public/MessageProcessor.h 9 | Public/MessageProcessorExDependencies.h 10 | Public/Network.h 11 | Public/PlayerMovementUpdate.h 12 | ) 13 | 14 | target_include_directories(ClientLib 15 | PRIVATE 16 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 17 | PUBLIC 18 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 19 | ) 20 | -------------------------------------------------------------------------------- /Source/ClientLib/Network/Public/ConnectionError.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Client 6 | { 7 | 8 | /** 9 | * Communicates that a connection error occurred. 10 | */ 11 | struct ConnectionError { 12 | enum class Type { 13 | Failed, /*!< We failed to connect. */ 14 | Disconnected /*!< We lost our connection to the server. */ 15 | }; 16 | 17 | /** The type of connection error that occurred. */ 18 | Type type{Type::Disconnected}; 19 | }; 20 | 21 | } // End namespace Client 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/ClientLib/Network/Public/IMessageProcessorExtension.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Defines an extension for the engine's Client::MessageProcessor class. 13 | * 14 | * Extensions are implemented by the project, and are given generic functions 15 | * ("hooks") in which they can implement relevant project logic. 16 | * 17 | * The project can register the extension class with the engine through 18 | * Application::registerMessageProcessorExtension(). 19 | */ 20 | class IMessageProcessorExtension 21 | { 22 | public: 23 | // Canonical constructor (derived class must implement): 24 | // MessageProcessorExtension(const MessageProcessorExDependencies& deps) 25 | 26 | /** 27 | * Called when a message is received that the engine doesn't have a handler 28 | * for. 29 | */ 30 | virtual void processReceivedMessage(Uint8 messageType, Uint8* messageBuffer, 31 | std::size_t messageSize) 32 | = 0; 33 | }; 34 | 35 | } // namespace Client 36 | } // namespace AM 37 | -------------------------------------------------------------------------------- /Source/ClientLib/Network/Public/MessageProcessorExDependencies.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | class EventDispatcher; 6 | 7 | namespace Client 8 | { 9 | 10 | /** 11 | * Defines the dependencies that will be provided to the project's 12 | * MessageProcessorExtension class. 13 | */ 14 | struct MessageProcessorExDependencies { 15 | public: 16 | EventDispatcher& networkEventDispatcher; 17 | }; 18 | 19 | } // namespace Client 20 | } // namespace AM 21 | -------------------------------------------------------------------------------- /Source/ClientLib/Network/Public/PlayerMovementUpdate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MovementState.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | /** 11 | * Holds updated movement state for the player entity. 12 | * 13 | * This isn't an actual message that gets sent by the server, instead it gets 14 | * split out when we receive a ComponentUpdate with the relevant data. 15 | */ 16 | struct PlayerMovementUpdate : public MovementState { 17 | /** The tick that this update corresponds to. */ 18 | Uint32 tickNum{0}; 19 | }; 20 | 21 | } // End namespace Client 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/ClientLib/Renderer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ClientLib 2 | PRIVATE 3 | Private/Renderer.cpp 4 | Private/WorldSpriteSorter.cpp 5 | PUBLIC 6 | Public/IRendererExtension.h 7 | Public/Renderer.h 8 | Public/RendererExDependencies.h 9 | Public/SpriteSortInfo.h 10 | Public/WorldSpriteSorter.h 11 | ) 12 | 13 | target_include_directories(ClientLib 14 | PRIVATE 15 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 16 | PUBLIC 17 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 18 | ) 19 | -------------------------------------------------------------------------------- /Source/ClientLib/Renderer/Public/RendererExDependencies.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct SDL_Renderer; 6 | 7 | namespace AM 8 | { 9 | class World; 10 | class UserInterface; 11 | 12 | namespace Client 13 | { 14 | 15 | /** 16 | * Defines the dependencies that will be provided to the project's 17 | * RendererExtension class. 18 | */ 19 | struct RendererExDependencies { 20 | public: 21 | SDL_Renderer* sdlRenderer; 22 | 23 | World& world; 24 | 25 | UserInterface& userInterface; 26 | 27 | std::function getSimTickProgress; 28 | }; 29 | 30 | } // namespace Client 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Private/ItemData/ItemData.cpp: -------------------------------------------------------------------------------- 1 | #include "ItemData.h" 2 | #include "Log.h" 3 | 4 | namespace AM 5 | { 6 | namespace Client 7 | { 8 | ItemData::ItemData() 9 | : ItemDataBase() 10 | { 11 | } 12 | 13 | } // End namespace Client 14 | } // End namespace AM 15 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Private/ReplicationTickOffset.cpp: -------------------------------------------------------------------------------- 1 | #include "ReplicationTickOffset.h" 2 | #include "Log.h" 3 | 4 | namespace AM 5 | { 6 | namespace Client 7 | { 8 | 9 | void ReplicationTickOffset::applyAdjustment(int adjustment) 10 | { 11 | // We set our client ahead of the server by an amount equal to our latency, 12 | // but this means that received messages will appear to be doubly far into 13 | // the past. 14 | // To account for this, we double the adjustment before applying. 15 | // We also negate it since we're reversing the direction. 16 | offset += (-2 * adjustment); 17 | 18 | if (offset >= 0) { 19 | LOG_FATAL("Adjusted replication tick offset too far into the " 20 | "future. offset: %u", 21 | offset); 22 | } 23 | } 24 | 25 | int ReplicationTickOffset::get() const 26 | { 27 | return offset; 28 | } 29 | 30 | } // End namespace Client 31 | } // End namespace AM 32 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Private/World.cpp: -------------------------------------------------------------------------------- 1 | #include "World.h" 2 | #include "Simulation.h" 3 | #include "Network.h" 4 | #include "GraphicData.h" 5 | #include "ItemData.h" 6 | #include "CastableData.h" 7 | #include "EnttGroups.h" 8 | 9 | namespace AM 10 | { 11 | namespace Client 12 | { 13 | World::World(Simulation& inSimulation, Network& inNetwork, 14 | const GraphicData& inGraphicData, const ItemData& inItemData, 15 | const CastableData& inCastableData) 16 | : registry{} 17 | , playerEntity{entt::null} 18 | , entityLocator{registry} 19 | , collisionLocator{} 20 | , tileMap{inGraphicData, collisionLocator} 21 | , castHelper{inSimulation, inNetwork, inItemData, inCastableData} 22 | { 23 | // Initialize our entt groups, before anyone tries to use them. 24 | EnttGroups::init(registry); 25 | } 26 | 27 | } // End namespace Client 28 | } // End namespace AM 29 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/AVSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | namespace Client 8 | { 9 | class World; 10 | class GraphicData; 11 | struct VisualEffectState; 12 | 13 | /** 14 | * Updates audio/visual effects and entities. 15 | * 16 | * A/V effects are attached to a particular entity, and follow that entity 17 | * around for a set period of time. These are used for e.g. a power-up effect. 18 | * 19 | * A/V entities are spawned as local-only entities, and have a set of logic 20 | * to perform before being destroyed. These are used for e.g. a blizzard spell. 21 | */ 22 | class AVSystem 23 | { 24 | public: 25 | AVSystem(World& inWorld, const GraphicData& inGraphicData); 26 | 27 | /** 28 | * Updates A/V effects and entities. 29 | */ 30 | void updateAVEffectsAndEntities(); 31 | 32 | private: 33 | /** 34 | * Updates all AVEffects components. 35 | */ 36 | void updateAVEffects(); 37 | 38 | /** 39 | * Updates all of the given visual effects. 40 | */ 41 | void updateVisualEffects(std::vector& visualEffects); 42 | 43 | /** Used to access entity data. */ 44 | World& world; 45 | const GraphicData& graphicData; 46 | }; 47 | 48 | } // End namespace Client 49 | } // End namespace AM 50 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/CameraSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | struct Position; 6 | struct Camera; 7 | 8 | namespace Client 9 | { 10 | class World; 11 | 12 | /** 13 | * Moves camera entities according to their behavior. 14 | */ 15 | class CameraSystem 16 | { 17 | public: 18 | CameraSystem(World& inWorld); 19 | 20 | /** 21 | * Moves all cameras to their appropriate next positions. 22 | */ 23 | void moveCameras(); 24 | 25 | private: 26 | World& world; 27 | }; 28 | 29 | } // namespace Client 30 | } // namespace AM 31 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/CastableData/AVEntityState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AVEntity.h" 4 | #include "Vector3.h" 5 | #include "entt/fwd.hpp" 6 | #include "entt/entity/entity.hpp" 7 | #include 8 | 9 | namespace AM 10 | { 11 | namespace Client 12 | { 13 | 14 | /** 15 | * Defines a client-only entity for displaying audio/visual effects. 16 | */ 17 | struct AVEntityState { 18 | /** The definition that this entity is an instance of. 19 | Note: This should never be nullptr. */ 20 | std::reference_wrapper avEntity; 21 | 22 | /** The target entity, if one was provided. */ 23 | entt::entity targetEntity{entt::null}; 24 | 25 | /** The target position, if one was provided. */ 26 | Vector3 targetPosition{0, 0, 0}; 27 | 28 | /** The index within phases of the current phase. */ 29 | std::size_t currentPhaseIndex{0}; 30 | }; 31 | 32 | } // namespace Client 33 | } // namespace AM 34 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/CastableData/VisualEffectState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "VisualEffect.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Defines a single visual effect. 13 | * 14 | * Typically, this will be attached to an entity to display a temporary graphic, 15 | * e.g. showing a heal graphic when an entity uses a health item. 16 | * 17 | * When the graphic is done playing, this effect is automatically destroyed. 18 | */ 19 | struct VisualEffectState { 20 | /** The definition that this is an instance of. */ 21 | std::reference_wrapper visualEffect; 22 | 23 | //------------------------------------------------------------------------- 24 | // Timing state (managed by WorldSpriteSorter) 25 | //------------------------------------------------------------------------- 26 | /** A timestamp of when this effect was started. 27 | If 0, this effect has not yet started playing. */ 28 | double startTime{0}; 29 | }; 30 | 31 | } // namespace Client 32 | } // namespace AM 33 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/Components/AVEffects.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "VisualEffectState.h" 4 | #include 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace Client 10 | { 11 | 12 | /** 13 | * Tracks all audio/visual effects that are currently active on an entity. 14 | */ 15 | struct AVEffects { 16 | /** This entity's currently active visual effects. */ 17 | std::vector visualEffects{}; 18 | 19 | /** This entity's currently active audio effects. */ 20 | //std::vector avEffects{}; 21 | }; 22 | 23 | } // namespace Client 24 | } // namespace AM 25 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/Components/ClientCastState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CastableID.h" 4 | #include "CastInfo.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace Client 10 | { 11 | 12 | /** 13 | * Tracks whether an entity is currently casting a Castable. 14 | * 15 | * To match the behavior of Server::CastState, this component will only be 16 | * present on an entity if a cast is currently ongoing. It gets removed when 17 | * the cast ends. 18 | */ 19 | struct ClientCastState { 20 | /** The current cast's info. */ 21 | CastInfo castInfo{}; 22 | 23 | enum class State { 24 | /** A cast is ongoing. */ 25 | Casting, 26 | /** The cast has successfully completed and the "cast complete" 27 | graphic should be shown. */ 28 | CastComplete 29 | }; 30 | /** The casting state that the entity is currently in. */ 31 | State state{}; 32 | 33 | /** The tick that the current state will finish on. If 0, this cast hasn't 34 | been processed for the first time yet. */ 35 | Uint32 endTick{0}; 36 | }; 37 | 38 | } // namespace Client 39 | } // namespace AM 40 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/Components/ClientGraphicState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EntityGraphicType.h" 4 | #include "Rotation.h" 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | /** 11 | * Holds client-only graphic-related state. 12 | * 13 | * Note: This is modified by both the sim and Renderer/WorldSpriteSorter. 14 | * Usually only sim classes are allowed to update components, but it's 15 | * convenient here. 16 | */ 17 | struct ClientGraphicState 18 | { 19 | /** The entity's current graphic type. 20 | The systems that set this will make sure it's always a valid slot 21 | within the entity's graphic set. */ 22 | EntityGraphicType graphicType{}; 23 | 24 | /** The rotation of the current graphic. 25 | The systems that set this will make sure it's always a valid slot 26 | within the entity's graphic set. */ 27 | Rotation::Direction graphicDirection{}; 28 | 29 | //------------------------------------------------------------------------- 30 | // Timing state (managed by WorldSpriteSorter) 31 | //------------------------------------------------------------------------- 32 | /** A timestamp of when the current animation was started. */ 33 | double animationStartTime{}; 34 | 35 | /** If true, a new animation has begun and animationStartTime needs to be 36 | reset when its first frame is rendered. */ 37 | bool setStartTime{true}; 38 | }; 39 | 40 | } // namespace Client 41 | } // namespace AM 42 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/Components/InputHistory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Input.h" 4 | #include "Movement.h" 5 | #include "CircularBuffer.h" 6 | 7 | namespace AM 8 | { 9 | namespace Client 10 | { 11 | /** 12 | * Stores a history of inputs that have been applied to the player entity. 13 | * 14 | * Only used for the player entity. You can use this component to distinguish 15 | * between player and non-player entities. 16 | */ 17 | struct InputHistory { 18 | public: 19 | /** 20 | * The number of input snapshots that we'll remember. 21 | * TODO: If this is ever an issue, we can make CircularBuffer dynamic and 22 | * exponentially grow it, and remove this. 23 | */ 24 | static constexpr unsigned int LENGTH{20}; 25 | 26 | /** Tracks the inputs that were applied to this entity. 27 | Increasing indices are further back in time--if index 0 is the current 28 | tick, index 1 is the previous tick, etc. */ 29 | CircularBuffer inputHistory; 30 | }; 31 | 32 | } // namespace Client 33 | } // namespace AM 34 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/Components/NeedsAdjacentChunks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Client 6 | { 7 | /** 8 | * Used to flag that we've just connected or just teleported and need to load 9 | * all adjacent tile map chunks. 10 | */ 11 | struct NeedsAdjacentChunks { 12 | }; 13 | 14 | } // namespace Client 15 | } // namespace AM 16 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/GraphicData/AnimationRenderData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Vector3.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Holds a animation's rendering-related data. 13 | * 14 | * We store any rendering-only data separately, so the server can optimally 15 | * access only the data it needs. 16 | * 17 | * See Animation.h for the rest of the animation data. 18 | */ 19 | struct AnimationRenderData { 20 | /** Only used for entities, during render sorting. 21 | When entities change animation, the new animation needs to line up with 22 | the old one so the entity doesn't look like it's teleporting around. 23 | If non-null, this is the model-space point that should be aligned 24 | with IdleSouth. */ 25 | std::optional entityAlignmentAnchor{}; 26 | }; 27 | 28 | } // End namespace Client 29 | } // End namespace AM 30 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/GraphicData/SpriteRenderData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AssetCache.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Holds a sprite's rendering-related data. 13 | * 14 | * We store any rendering-only data separately, so the server can optimally 15 | * access only the data it needs. 16 | * 17 | * See Sprite.h for the rest of the sprite data. 18 | */ 19 | struct SpriteRenderData { 20 | /** The relative path to the sprite sheet image file that holds this 21 | sprite. Used for passing the sprite to our UI library, which has its 22 | own texture cache. */ 23 | std::string spriteSheetRelPath{}; 24 | 25 | /** The texture that contains this sprite. */ 26 | std::shared_ptr texture{}; 27 | 28 | /** This sprite's actual-space UV position and size within its texture. */ 29 | SDL_Rect textureExtent{0, 0, 0, 0}; 30 | 31 | /** The actual-space point within the sprite where the "stage" starts. 32 | The "stage" is the coordinate space that we overlay onto the sprite 33 | image. */ 34 | SDL_Point stageOrigin{0, 0}; 35 | 36 | /** If true, this sprite will have its alpha premultiplied. */ 37 | bool premultiplyAlpha{false}; 38 | }; 39 | 40 | } // End namespace Client 41 | } // End namespace AM 42 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/IconData/IconRenderData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AssetCache.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Holds a icon's rendering-related data. 13 | * 14 | * See Icon.h for more info. 15 | */ 16 | struct IconRenderData { 17 | /** The relative path to the icon sheet image file that holds this 18 | icon. Used for passing the icon to our UI library, which has its 19 | own texture cache. */ 20 | std::string iconSheetRelPath{}; 21 | 22 | /** UV position and size in texture. */ 23 | SDL_Rect textureExtent{0, 0, 0, 0}; 24 | }; 25 | 26 | } // End namespace Client 27 | } // End namespace AM 28 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/ItemData/ItemCache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Item.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Used to save/load ItemCache.bin. 13 | * 14 | * Holds a list of items in a serializable form. 15 | */ 16 | struct ItemCache 17 | { 18 | /** Used as a "we should never hit this" cap on the number of items in the 19 | cache. */ 20 | static constexpr std::size_t MAX_ITEMS{10000}; 21 | 22 | struct ItemEntry { 23 | Item item{}; 24 | ItemVersion version{}; 25 | }; 26 | 27 | std::vector items{}; 28 | }; 29 | 30 | template 31 | void serialize(S& serializer, ItemCache::ItemEntry& itemEntry) 32 | { 33 | serializer.object(itemEntry.item); 34 | serializer.value2b(itemEntry.version); 35 | } 36 | 37 | template 38 | void serialize(S& serializer, ItemCache& itemCache) 39 | { 40 | serializer.container(itemCache.items, ItemCache::MAX_ITEMS); 41 | } 42 | 43 | } // End namespace Client 44 | } // End namespace AM 45 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/ItemData/ItemData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ItemDataBase.h" 4 | 5 | namespace AM 6 | { 7 | namespace Client 8 | { 9 | /** 10 | * See ItemDataBase class comment. 11 | */ 12 | class ItemData : public ItemDataBase 13 | { 14 | public: 15 | ItemData(); 16 | }; 17 | 18 | } // End namespace Client 19 | } // End namespace AM 20 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/ItemSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ItemUpdate.h" 4 | #include "CombineItems.h" 5 | #include "QueuedEvents.h" 6 | 7 | namespace AM 8 | { 9 | namespace Client 10 | { 11 | class World; 12 | class Network; 13 | class ItemData; 14 | 15 | /** 16 | * Processes item definition updates and item combination updates. 17 | */ 18 | class ItemSystem 19 | { 20 | public: 21 | ItemSystem(World& inWorld, Network& inNetwork, ItemData& inItemData); 22 | 23 | /** 24 | * Processes item update messages. 25 | */ 26 | void processItemUpdates(); 27 | 28 | private: 29 | /** 30 | * Loads all items from ItemCache.bin into ItemData. 31 | */ 32 | void loadItemCache(); 33 | 34 | /** 35 | * Saves all items from ItemData into ItemCache.bin. 36 | */ 37 | void saveItemCache(); 38 | 39 | /** Used for updating inventories. */ 40 | World& world; 41 | /** Used for sending requests and receiving item data. */ 42 | Network& network; 43 | /** Used for accessing item data and subscribing to updates. */ 44 | ItemData& itemData; 45 | 46 | EventQueue itemUpdateQueue; 47 | EventQueue combineItemsQueue; 48 | }; 49 | 50 | } // namespace Client 51 | } // namespace AM 52 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/ReplicationTickOffset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Config.h" 4 | 5 | namespace AM 6 | { 7 | namespace Client 8 | { 9 | /** 10 | * Represents a tick offset used while replicating non-predicted state, such 11 | * as NPC movement and tile map updates. 12 | * 13 | * This tick offset is negative, representing some point in the past. 14 | */ 15 | struct ReplicationTickOffset { 16 | public: 17 | /** 18 | * Applies the given tick adjustment (received from the server) to 19 | * this offset. 20 | */ 21 | void applyAdjustment(int adjustment); 22 | 23 | /** 24 | * Returns the value of this tick offset. 25 | */ 26 | int get() const; 27 | 28 | private: 29 | /** How far into the past to replicate at. 30 | e.g. If offset == -5, on tick 15 we'll replicate NPC data for tick 10. 31 | */ 32 | int offset{Config::INITIAL_REPLICATION_OFFSET}; 33 | }; 34 | 35 | } // End namespace Client 36 | } // End namespace AM 37 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/SimulationExDependencies.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | class EventDispatcher; 6 | class CastableData; 7 | 8 | namespace Client 9 | { 10 | class Simulation; 11 | class Network; 12 | class GraphicData; 13 | class IconData; 14 | class ItemData; 15 | 16 | /** 17 | * Defines the dependencies that will be provided to the project's 18 | * SimulationExtension class. 19 | */ 20 | struct SimulationExDependencies { 21 | public: 22 | Simulation& simulation; 23 | 24 | EventDispatcher& uiEventDispatcher; 25 | 26 | Network& network; 27 | 28 | GraphicData& graphicData; 29 | 30 | IconData& iconData; 31 | 32 | ItemData& itemData; 33 | 34 | CastableData& castableData; 35 | }; 36 | 37 | } // namespace Client 38 | } // namespace AM 39 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/TileMap/TileMap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TileMapBase.h" 4 | #include "entt/signal/sigh.hpp" 5 | #include 6 | 7 | namespace AM 8 | { 9 | class CollisionLocator; 10 | 11 | namespace Client 12 | { 13 | class GraphicData; 14 | 15 | /** 16 | * Owns and manages the world's tile map state. 17 | * Tiles are conceptually organized into 16x16 chunks. 18 | * 19 | * Tile map data is streamed from the server at runtime. 20 | */ 21 | class TileMap : public TileMapBase 22 | { 23 | public: 24 | /** 25 | * Attempts to parse TileMap.bin and construct the tile map. 26 | * 27 | * Errors if TileMap.bin doesn't exist or it fails to parse. 28 | */ 29 | TileMap(const GraphicData& inGraphicData, 30 | CollisionLocator& inCollisionLocator); 31 | 32 | /** 33 | * Sets the size of the map and resizes the chunks vector. 34 | */ 35 | void setMapSize(Uint16 inMapXLengthChunks, Uint16 inMapYLengthChunks, 36 | Uint16 inMapZLengthChunks); 37 | 38 | private: 39 | entt::sigh sizeChangedSig; 40 | 41 | public: 42 | /** The tile map's size (extent) has changed. */ 43 | entt::sink> sizeChanged; 44 | }; 45 | 46 | } // End namespace Client 47 | } // End namespace AM 48 | -------------------------------------------------------------------------------- /Source/ClientLib/Simulation/Public/WorldObjectID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TileLayerID.h" 4 | #include "entt/fwd.hpp" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace Client 10 | { 11 | 12 | /** 13 | * A variant used when we need to generically identify an object from the 14 | * simulation's World. 15 | * 16 | * Useful, e.g., when returning the object that the user clicked on. 17 | * 18 | * Note: "Object" doesn't mean the same as when we say "Object tile layer". 19 | * A better name for this would be welcome. 20 | */ 21 | using WorldObjectID = std::variant; 22 | 23 | } // namespace Client 24 | } // namespace AM 25 | -------------------------------------------------------------------------------- /Source/ClientLib/UserInterface/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ClientLib 2 | PRIVATE 3 | Private/UserInterface.cpp 4 | Private/WorldObjectLocator.cpp 5 | PUBLIC 6 | Public/IUserInterfaceExtension.h 7 | Public/PhantomSpriteInfo.h 8 | Public/SpriteColorModInfo.h 9 | Public/UserInterface.h 10 | Public/UserInterfaceExDependencies.h 11 | Public/WorldObjectLocator.h 12 | ) 13 | 14 | target_include_directories(ClientLib 15 | PRIVATE 16 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 17 | PUBLIC 18 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 19 | ) 20 | -------------------------------------------------------------------------------- /Source/ClientLib/UserInterface/Public/SpriteColorModInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WorldObjectID.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Client 9 | { 10 | 11 | /** 12 | * Used by the UI when it wants a sprite to have its color and/or transparency 13 | * modified. 14 | */ 15 | struct SpriteColorModInfo { 16 | /** The world object that we want to modify the color of. 17 | Note: Since phantom entities don't have an entity ID, you can use 18 | entt::null to target them. */ 19 | WorldObjectID objectToModify; 20 | 21 | /** The color and transparency to multiply the sprite by. 22 | Note: Instead of directly multiplying the sprite by this color (which 23 | would make it darker), we render an additional sprite with an 24 | additive blend mode and multiply that one by this color. 25 | Alpha is applied to both sprites. */ 26 | SDL_Color colorMod{0, 0, 0, 255}; 27 | }; 28 | 29 | } // End namespace Client 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/ClientLib/UserInterface/Public/UserInterfaceExDependencies.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct SDL_Renderer; 4 | 5 | namespace AM 6 | { 7 | class EventDispatcher; 8 | 9 | namespace Client 10 | { 11 | class Simulation; 12 | class WorldObjectLocator; 13 | class Network; 14 | class GraphicData; 15 | class ItemData; 16 | class IconData; 17 | 18 | /** 19 | * Defines the dependencies that will be provided to the project's 20 | * UserInterfaceExtension class. 21 | */ 22 | struct UserInterfaceExDependencies { 23 | public: 24 | /** Used for viewing world data and subscribing to signals. */ 25 | Simulation& simulation; 26 | 27 | /** Used for finding entities or tile layers that a mouse event hit. */ 28 | const WorldObjectLocator& worldObjectLocator; 29 | 30 | /** Used to send events to the sim. */ 31 | EventDispatcher& uiEventDispatcher; 32 | 33 | /** Used to send and receive messages from the server. */ 34 | Network& network; 35 | 36 | /** Used for rendering. */ 37 | SDL_Renderer* sdlRenderer; 38 | 39 | /** Used for getting sprite and animation data. */ 40 | GraphicData& graphicData; 41 | 42 | /** Used for getting icon data. */ 43 | IconData& iconData; 44 | 45 | /** Used for getting item data and subscribing to updates. */ 46 | ItemData& itemData; 47 | }; 48 | 49 | } // namespace Client 50 | } // namespace AM 51 | -------------------------------------------------------------------------------- /Source/ClientLib/Utility/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ClientLib 2 | PRIVATE 3 | Private/ClientTransforms.cpp 4 | PUBLIC 5 | Public/ClientTransforms.h 6 | ) 7 | 8 | target_include_directories(ClientLib 9 | PRIVATE 10 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 11 | PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 13 | ) 14 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/README.md: -------------------------------------------------------------------------------- 1 | This directory provides examples for each expected file in the project's `EngineSupplement` directory. 2 | 3 | The files in this directory are not built or used in any way. 4 | 5 | Example README.md for the base of the EngineSupplement directory: 6 | ``` 7 | In this directory, the project provides files that will be built as part of the engine. 8 | 9 | We use this mechanism for a few things, such as: 10 | * Enum definitions 11 | * There's no good alternative for providing project enums to the engine. 12 | * Config headers 13 | * For any configuration constants that we don't want to expose to the end user. 14 | * Type lists and Components 15 | * We tested an alternative using type erasure, but it performed significantly worse than providing type definitions to the engine and using a variant. 16 | 17 | ** Note: Since these files are built as part of the engine, they can't depend on any project files. ** 18 | ``` 19 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/Server/Simulation/Public/TypeLists/ProjectAITypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "boost/mp11/list.hpp" 4 | 5 | namespace AM 6 | { 7 | // Note: AI is server-only. 8 | namespace Server 9 | { 10 | /** 11 | * Add AI classes to this list to have them be processed by the engine. 12 | * 13 | * Note: Every type in this list must be derived from AILogic. 14 | */ 15 | using ProjectAITypes = boost::mp11::mp_list<>; 16 | 17 | } // End namespace Server 18 | } // End namespace AM 19 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/Server/Simulation/Public/TypeLists/ProjectObservedComponentTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "boost/mp11/list.hpp" 4 | 5 | namespace AM 6 | { 7 | // Note: Observed components are server-only. 8 | namespace Server 9 | { 10 | /** 11 | * See EngineReplicatedComponentTypes.h for more info. 12 | */ 13 | using ProjectObservedComponentTypes = boost::mp11::mp_list<>; 14 | 15 | } // End namespace Server 16 | } // End namespace AM 17 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/Shared/Simulation/Public/EntityGraphicType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineEntityGraphicType.h" 4 | #include "AMAssert.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | 10 | /** 11 | * The types of graphics that may be displayed to represent an entity, 12 | * depending on what that entity's state is. 13 | * 14 | * Each entity graphic type can face 8 directions, depending on the entity's 15 | * Rotation component. 16 | * 17 | * Controls the graphic types that show up for entity graphic sets in 18 | * ResourceImporter. 19 | */ 20 | enum class EntityGraphicType : Uint8 { 21 | // Engine graphic types (copied here so we can use one strongly-typed enum). 22 | NotSet = static_cast(EngineEntityGraphicType::NotSet), 23 | /** Note: All graphic sets are expected to contain IdleSouth. */ 24 | Idle = static_cast(EngineEntityGraphicType::Idle), 25 | Run = static_cast(EngineEntityGraphicType::Run), 26 | Crouch = static_cast(EngineEntityGraphicType::Crouch), 27 | Jump = static_cast(EngineEntityGraphicType::Jump), 28 | 29 | // Project graphic types. 30 | PROJECT_START = static_cast(EngineEntityGraphicType::PROJECT_START), 31 | // MyGraphicType, 32 | 33 | PROJECT_END 34 | }; 35 | 36 | } // End namespace AM 37 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/Shared/Simulation/Public/EntityInteractionType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineEntityInteractionType.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | /** 10 | * The types of interactions that a user may be able to perform on an entity. 11 | */ 12 | enum class EntityInteractionType : Uint8 { 13 | // Engine interactions (copied here so we can use one strongly-typed enum). 14 | NotSet = static_cast(EngineEntityInteractionType::NotSet), 15 | Talk = static_cast(EngineEntityInteractionType::Talk), 16 | }; 17 | 18 | } // End namespace AM 19 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/Shared/Simulation/Public/ItemInteractionType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineItemInteractionType.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | /** 10 | * The types of interactions that a user may be able to perform on an item. 11 | */ 12 | enum class ItemInteractionType : Uint8 { 13 | // Engine interactions (copied here so we can use one strongly-typed enum). 14 | NotSet = static_cast(EngineItemInteractionType::NotSet), 15 | 16 | // Note: All items support Examine, Destroy (handled by 17 | // InventoryDeleteItem), and UseOn (handled by CombineItems and 18 | // UseItemOnEntityRequest). 19 | UseOn = static_cast(EngineItemInteractionType::UseOn), 20 | Destroy = static_cast(EngineItemInteractionType::Destroy), 21 | Examine = static_cast(EngineItemInteractionType::Examine), 22 | 23 | // Project interactions. 24 | // MyInteraction = 25 | // static_cast(EngineItemInteractionType::PROJECT_START), 26 | }; 27 | 28 | } // End namespace AM 29 | -------------------------------------------------------------------------------- /Source/EngineSupplementExamples/Shared/Simulation/Public/TypeLists/ProjectReplicatedComponentTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "boost/mp11/list.hpp" 4 | 5 | namespace AM 6 | { 7 | /** 8 | * See EngineReplicatedComponentTypes.h for more info. 9 | */ 10 | using ProjectReplicatedComponentTypes = boost::mp11::mp_list<>; 11 | 12 | } // End namespace AM 13 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ResourceImporter 2 | PUBLIC 3 | Public/Config.h 4 | ) 5 | 6 | target_include_directories(ResourceImporter 7 | PUBLIC 8 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 9 | ) 10 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Private/EditorSprite.cpp: -------------------------------------------------------------------------------- 1 | #include "EditorSprite.h" 2 | #include "BoundingBoxModel.h" 3 | 4 | namespace AM 5 | { 6 | namespace ResourceImporter 7 | { 8 | 9 | const BoundingBox& 10 | EditorSprite::getModelBounds(const BoundingBoxModel& boundingBoxModel) const 11 | { 12 | if (modelBoundsID) { 13 | return boundingBoxModel.getBoundingBox(modelBoundsID).modelBounds; 14 | } 15 | else { 16 | return customModelBounds; 17 | } 18 | } 19 | 20 | } // End namespace ResourceImporter 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorBoundingBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BoundingBoxID.h" 4 | #include "BoundingBox.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | 12 | /** 13 | * Holds the data necessary for editing and saving a bounding box. 14 | * Part of BoundingBoxModel. 15 | */ 16 | struct EditorBoundingBox { 17 | /** This bounding box's unique numeric identifier. */ 18 | BoundingBoxID numericID{NULL_BOUNDING_BOX_ID}; 19 | 20 | /** Unique display name, shown in the UI. */ 21 | std::string displayName{""}; 22 | 23 | /** Model-space bounding box. */ 24 | BoundingBox modelBounds{}; 25 | }; 26 | 27 | } // namespace ResourceImporter 28 | } // namespace AM 29 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorEntityGraphicSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicID.h" 4 | #include "GraphicSetIDs.h" 5 | #include "EntityGraphicType.h" 6 | #include "Rotation.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace AM 13 | { 14 | namespace ResourceImporter 15 | { 16 | /** 17 | * Holds the data necessary for editing and saving an entity graphic set. 18 | * Part of EntityGraphicSetModel. 19 | */ 20 | struct EditorEntityGraphicSet { 21 | /** This graphic set's unique numeric identifier. 22 | Note: This ID may change when this graphic set is saved to the json. */ 23 | EntityGraphicSetID numericID{0}; 24 | 25 | /** Unique display name, shown in the UI. */ 26 | std::string displayName{""}; 27 | 28 | /** The entity graphic types that this set contains. 29 | Each graphic type is associated with an array of up to 8 graphics, one 30 | for each possible rotation of the entity. 31 | The Idle graphic type will always be present. All others are optional. 32 | If any slots weren't assigned a graphic, they will be set to 33 | NULL_GRAPHIC_ID in the array. */ 34 | std::unordered_map> 36 | graphicIDs{}; 37 | }; 38 | 39 | } // namespace ResourceImporter 40 | } // namespace AM 41 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorFloorGraphicSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rotation.h" 4 | #include "GraphicID.h" 5 | #include "GraphicSetIDs.h" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace AM 11 | { 12 | namespace ResourceImporter 13 | { 14 | /** 15 | * Holds the data necessary for editing and saving a floor graphic set. 16 | * Part of GraphicSetModel. 17 | */ 18 | struct EditorFloorGraphicSet { 19 | /** This graphic set's unique numeric identifier. 20 | Note: This ID may change when this graphic set is saved to the json. */ 21 | FloorGraphicSetID numericID{0}; 22 | 23 | /** Unique display name, shown in the UI. */ 24 | std::string displayName{""}; 25 | 26 | /** The numeric IDs for each graphic in this set. 27 | Floors support 8 directions of rotation. At least 1 graphic 28 | must be set. If a direction isn't provided, it should be set to 29 | NULL_GRAPHIC_ID. */ 30 | std::array graphicIDs{ 31 | /* NULL_GRAPHIC_ID */ }; 32 | }; 33 | 34 | } // namespace ResourceImporter 35 | } // namespace AM 36 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorIcon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IconID.h" 4 | #include 5 | #include 6 | #include 7 | 8 | namespace AM 9 | { 10 | namespace ResourceImporter 11 | { 12 | /** 13 | * Holds the data necessary for editing and saving an icon. 14 | * Part of IconModel. 15 | */ 16 | struct EditorIcon { 17 | /** This icon's unique numeric identifier. 18 | Note: This ID may change when this icon is saved to the json. */ 19 | IconID numericID{0}; 20 | 21 | /** The unique relPath of the icon sheet that this icon is from. */ 22 | std::string parentIconSheetPath{""}; 23 | 24 | /** Unique display name, shown in the UI. */ 25 | std::string displayName{""}; 26 | 27 | /** UV position and size in texture. */ 28 | SDL_Rect textureExtent{0, 0, 0, 0}; 29 | }; 30 | 31 | } // namespace ResourceImporter 32 | } // namespace AM 33 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorIconSheet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IconID.h" 4 | #include 5 | #include 6 | #include 7 | 8 | namespace AM 9 | { 10 | namespace ResourceImporter 11 | { 12 | /** 13 | * Holds the data necessary for editing and saving an icon sheet. 14 | * Part of IconModel. 15 | */ 16 | struct EditorIconSheet { 17 | /** The path to the icon sheet image file, relative to the application's 18 | base directory. */ 19 | std::string relPath{}; 20 | 21 | /** The runtime IDs for each icon in this sheet. */ 22 | std::vector iconIDs{}; 23 | }; 24 | 25 | } // namespace ResourceImporter 26 | } // namespace AM 27 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorObjectGraphicSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Rotation.h" 4 | #include "GraphicID.h" 5 | #include "GraphicSetIDs.h" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace AM 11 | { 12 | namespace ResourceImporter 13 | { 14 | /** 15 | * Holds the data necessary for editing and saving an object graphic set. 16 | * Part of GraphicSetModel. 17 | */ 18 | struct EditorObjectGraphicSet { 19 | /** This graphic set's unique numeric identifier. 20 | Note: This ID may change when this graphic set is saved to the json. */ 21 | ObjectGraphicSetID numericID{0}; 22 | 23 | /** Unique display name, shown in the UI. */ 24 | std::string displayName{""}; 25 | 26 | /** The numeric IDs for each graphic in this set. 27 | Objects support 8 directions of rotation. At least 1 graphic must be 28 | set. If a direction isn't provided, it should be set to 29 | NULL_GRAPHIC_ID. */ 30 | std::array graphicIDs{ 31 | NULL_GRAPHIC_ID, NULL_GRAPHIC_ID, NULL_GRAPHIC_ID, NULL_GRAPHIC_ID, 32 | NULL_GRAPHIC_ID, NULL_GRAPHIC_ID, NULL_GRAPHIC_ID, NULL_GRAPHIC_ID}; 33 | }; 34 | 35 | } // namespace ResourceImporter 36 | } // namespace AM 37 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorSpriteSheet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SpriteSheetID.h" 4 | #include "SpriteID.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace AM 10 | { 11 | namespace ResourceImporter 12 | { 13 | /** 14 | * Holds the data necessary for editing and saving a sprite sheet. 15 | * Part of SpriteModel. 16 | */ 17 | struct EditorSpriteSheet { 18 | /** This sprite sheet's unique numeric identifier. 19 | Note: Sprite sheet numeric IDs aren't saved to the json or used by 20 | the engine, so we just generate new ones each time the 21 | importer is ran. */ 22 | SpriteSheetID numericID{NULL_SPRITE_SHEET_ID}; 23 | 24 | /** Unique display name. Shown in the UI, and used as the name of the 25 | exported sprite sheet image file. */ 26 | std::string displayName{""}; 27 | 28 | /** The width of the generated sprite sheet texture. */ 29 | int textureWidth{0}; 30 | /** The height of the generated sprite sheet texture. */ 31 | int textureHeight{0}; 32 | 33 | /** The numeric IDs for each sprite in this sheet. */ 34 | std::vector spriteIDs{}; 35 | }; 36 | 37 | } // namespace ResourceImporter 38 | } // namespace AM 39 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorTerrainGraphicSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Terrain.h" 4 | #include "GraphicID.h" 5 | #include "GraphicSetIDs.h" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace AM 11 | { 12 | namespace ResourceImporter 13 | { 14 | /** 15 | * Holds the data necessary for editing and saving a terrain graphic set. 16 | * Part of GraphicSetModel. 17 | */ 18 | struct EditorTerrainGraphicSet { 19 | /** This graphic set's unique numeric identifier. 20 | Note: This ID may change when this graphic set is saved to the json. */ 21 | TerrainGraphicSetID numericID{0}; 22 | 23 | /** Unique display name, shown in the UI. */ 24 | std::string displayName{""}; 25 | 26 | /** The numeric IDs for each graphic in this set. 27 | If a graphic isn't provided, it should be set to NULL_GRAPHIC_ID. */ 28 | std::array graphicIDs{ 29 | /* NULL_GRAPHIC_ID */ }; 30 | }; 31 | 32 | } // namespace ResourceImporter 33 | } // namespace AM 34 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/EditorWallGraphicSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Wall.h" 4 | #include "GraphicID.h" 5 | #include "GraphicSetIDs.h" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace AM 11 | { 12 | namespace ResourceImporter 13 | { 14 | /** 15 | * Holds the data necessary for editing and saving a floor graphic set. 16 | * Part of GraphicSetModel. 17 | */ 18 | struct EditorWallGraphicSet { 19 | /** This graphic set's unique numeric identifier. 20 | Note: This ID may change when this graphic set is saved to the json. */ 21 | WallGraphicSetID numericID{0}; 22 | 23 | /** Unique display name, shown in the UI. */ 24 | std::string displayName{""}; 25 | 26 | /** The numeric IDs for each graphic in this set. 27 | Walls require the 4 types of wall graphics that our modular wall 28 | system uses. */ 29 | std::array graphicIDs{ 30 | /* NULL_GRAPHIC_ID */ }; 31 | }; 32 | 33 | } // namespace ResourceImporter 34 | } // namespace AM 35 | -------------------------------------------------------------------------------- /Source/ResourceImporter/DataModel/Public/SpriteSheetID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** A sprite sheet's numeric ID. */ 9 | using SpriteSheetID = Uint32; 10 | 11 | /** 12 | * The ID of the "null sprite sheet", or the ID used to indicate that a sprite 13 | * sheet is not present. 14 | * 15 | * Note: Since the null ID is 0, you can do null checks like 16 | * "if (spriteSheetID)". 17 | */ 18 | static constexpr SpriteSheetID NULL_SPRITE_SHEET_ID{0}; 19 | 20 | } // End namespace AM 21 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Launch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ResourceImporter 2 | PRIVATE 3 | Private/main.cpp 4 | Private/Application.cpp 5 | PUBLIC 6 | Public/Application.h 7 | ) 8 | 9 | target_include_directories(ResourceImporter 10 | PRIVATE 11 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 13 | ) 14 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Launch/Private/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Log.h" 2 | #include "Application.h" 3 | 4 | #include "SDL2pp/Exception.hh" 5 | 6 | #include 7 | 8 | using namespace AM; 9 | using namespace AM::ResourceImporter; 10 | 11 | // SDL2 needs this signature for main, but we don't use the parameters. 12 | int main(int, char**) 13 | try { 14 | // Set up file logging. 15 | Log::enableFileLogging("ResourceImporter.log"); 16 | 17 | // Start the application (assumes control of the thread). 18 | Application app; 19 | app.start(); 20 | 21 | return 0; 22 | } catch (SDL2pp::Exception& e) { 23 | LOG_INFO("Error in: %s Reason: %s", e.GetSDLFunction().c_str(), 24 | e.GetSDLError().c_str()); 25 | return 1; 26 | } catch (std::exception& e) { 27 | LOG_INFO("%s", e.what()); 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Renderer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ResourceImporter 2 | PRIVATE 3 | Private/Renderer.cpp 4 | PUBLIC 5 | Public/Renderer.h 6 | ) 7 | 8 | target_include_directories(ResourceImporter 9 | PRIVATE 10 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 11 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 12 | ) 13 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Renderer/Private/Renderer.cpp: -------------------------------------------------------------------------------- 1 | #include "Renderer.h" 2 | #include "UserInterface.h" 3 | #include "Log.h" 4 | #include 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | Renderer::Renderer(SDL_Renderer* inSdlRenderer, UserInterface& inUI) 12 | : sdlRenderer{inSdlRenderer} 13 | , ui{inUI} 14 | { 15 | } 16 | 17 | void Renderer::render() 18 | { 19 | /* Render. */ 20 | // Clear the current rendering target to prepare for rendering. 21 | SDL_RenderClear(sdlRenderer); 22 | 23 | // Render the current UI screen. 24 | ui.render(); 25 | 26 | // Present the finished back buffer to the user's screen. 27 | SDL_RenderPresent(sdlRenderer); 28 | } 29 | 30 | bool Renderer::handleOSEvent(SDL_Event& event) 31 | { 32 | switch (event.type) { 33 | case SDL_WINDOWEVENT: 34 | // TODO: Handle this. 35 | return true; 36 | } 37 | 38 | return false; 39 | } 40 | 41 | } // namespace ResourceImporter 42 | } // namespace AM 43 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Renderer/Public/Renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "OSEventHandler.h" 4 | #include "PeriodicCaller.h" 5 | 6 | struct SDL_Renderer; 7 | 8 | namespace AM 9 | { 10 | namespace ResourceImporter 11 | { 12 | class UserInterface; 13 | 14 | /** 15 | * Renders the UI. 16 | */ 17 | class Renderer : public OSEventHandler 18 | { 19 | public: 20 | static constexpr unsigned int FRAMES_PER_SECOND{60}; 21 | static constexpr double FRAME_TIMESTEP_S{ 22 | 1.0 / static_cast(FRAMES_PER_SECOND)}; 23 | 24 | Renderer(SDL_Renderer* inSdlRenderer, UserInterface& inUI); 25 | 26 | /** 27 | * Renders the UI. 28 | */ 29 | void render(); 30 | 31 | /** 32 | * Handles window events. 33 | */ 34 | bool handleOSEvent(SDL_Event& event) override; 35 | 36 | private: 37 | SDL_Renderer* sdlRenderer; 38 | 39 | /** Used to begin the UI rendering. */ 40 | UserInterface& ui; 41 | }; 42 | 43 | } // namespace ResourceImporter 44 | } // namespace AM 45 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Private/TitleScreen.cpp: -------------------------------------------------------------------------------- 1 | #include "TitleScreen.h" 2 | #include "UserInterface.h" 3 | #include "AUI/Core.h" 4 | 5 | namespace AM 6 | { 7 | namespace ResourceImporter 8 | { 9 | TitleScreen::TitleScreen(UserInterface& inUserInterface, DataModel& inDataModel) 10 | : AUI::Screen("TitleScreen") 11 | , titleWindow{inUserInterface, inDataModel} 12 | { 13 | // Add our windows so they're included in rendering, etc. 14 | windows.push_back(titleWindow); 15 | } 16 | 17 | void TitleScreen::render() 18 | { 19 | // Fill the background with the background color. 20 | SDL_Renderer* renderer{AUI::Core::getRenderer()}; 21 | SDL_SetRenderDrawColor(renderer, 37, 37, 52, 255); 22 | SDL_RenderClear(renderer); 23 | 24 | // Update our window's layouts and render them. 25 | Screen::render(); 26 | } 27 | 28 | } // End namespace ResourceImporter 29 | } // End namespace AM 30 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Private/Widgets/MainButton.cpp: -------------------------------------------------------------------------------- 1 | #include "MainButton.h" 2 | #include "Paths.h" 3 | 4 | namespace AM 5 | { 6 | namespace ResourceImporter 7 | { 8 | MainButton::MainButton(const SDL_Rect& inLogicalExtent, 9 | const std::string& inText, 10 | const std::string& inDebugName) 11 | : AUI::Button(inLogicalExtent, inDebugName) 12 | { 13 | // Add our backgrounds. 14 | normalImage.setNineSliceImage(Paths::TEXTURE_DIR + "MainButton/Normal.png", 15 | {2, 2, 2, 2}); 16 | hoveredImage.setNineSliceImage( 17 | Paths::TEXTURE_DIR + "MainButton/Hovered.png", {2, 2, 2, 2}); 18 | pressedImage.setNineSliceImage( 19 | Paths::TEXTURE_DIR + "MainButton/Pressed.png", {2, 2, 2, 2}); 20 | disabledImage.setNineSliceImage( 21 | Paths::TEXTURE_DIR + "MainButton/Disabled.png", {2, 2, 2, 2}); 22 | 23 | // Set our text properties. 24 | text.setFont((Paths::FONT_DIR + "B612-Regular.ttf"), 18); 25 | text.setColor({255, 255, 255, 255}); 26 | text.setText(inText); 27 | } 28 | 29 | } // End namespace ResourceImporter 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Private/Widgets/MainTextInput.cpp: -------------------------------------------------------------------------------- 1 | #include "MainTextInput.h" 2 | #include "Paths.h" 3 | 4 | namespace AM 5 | { 6 | namespace ResourceImporter 7 | { 8 | MainTextInput::MainTextInput(const SDL_Rect& inLogicalExtent, 9 | const std::string& inDebugName) 10 | : AUI::TextInput(inLogicalExtent, inDebugName) 11 | { 12 | // Add our backgrounds. 13 | normalImage.setSimpleImage(Paths::TEXTURE_DIR + "TextInput/Normal.png"); 14 | hoveredImage.setSimpleImage(Paths::TEXTURE_DIR + "TextInput/Hovered.png"); 15 | focusedImage.setSimpleImage(Paths::TEXTURE_DIR + "TextInput/Selected.png"); 16 | disabledImage.setSimpleImage(Paths::TEXTURE_DIR + "TextInput/Disabled.png"); 17 | 18 | // Set our text properties. 19 | setTextFont((Paths::FONT_DIR + "B612-Regular.ttf"), 25); 20 | 21 | // Set our input box properties. 22 | setCursorWidth(2); 23 | } 24 | 25 | } // End namespace ResourceImporter 26 | } // End namespace AM 27 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Private/Widgets/MainThumbnail.cpp: -------------------------------------------------------------------------------- 1 | #include "MainThumbnail.h" 2 | #include "Paths.h" 3 | 4 | namespace AM 5 | { 6 | namespace ResourceImporter 7 | { 8 | MainThumbnail::MainThumbnail(const std::string& inDebugName) 9 | : AUI::Thumbnail({0, 0, 150, 150}, inDebugName) 10 | { 11 | // Add our backgrounds. 12 | hoveredImage.setSimpleImage(Paths::TEXTURE_DIR + "Thumbnail/Hovered.png"); 13 | activeImage.setSimpleImage(Paths::TEXTURE_DIR + "Thumbnail/Active.png"); 14 | backdropImage.setSimpleImage(Paths::TEXTURE_DIR + "Thumbnail/Backdrop.png"); 15 | selectedImage.setSimpleImage(Paths::TEXTURE_DIR + "Thumbnail/Selected.png"); 16 | 17 | // Move our thumbnail image to the right position. 18 | thumbnailImage.setLogicalExtent({27, 15, 96, 96}); 19 | 20 | // Set our text properties. 21 | setTextLogicalExtent({13, 120, 123, 20}); 22 | setTextFont((Paths::FONT_DIR + "B612-Regular.ttf"), 15); 23 | setTextColor({255, 255, 255, 255}); 24 | } 25 | 26 | } // End namespace ResourceImporter 27 | } // End namespace AM 28 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Private/Widgets/TitleButton.cpp: -------------------------------------------------------------------------------- 1 | #include "TitleButton.h" 2 | #include "Paths.h" 3 | 4 | namespace AM 5 | { 6 | namespace ResourceImporter 7 | { 8 | TitleButton::TitleButton(const SDL_Rect& inLogicalExtent, 9 | const std::string& inText, 10 | const std::string& inDebugName) 11 | : AUI::Button(inLogicalExtent, inDebugName) 12 | { 13 | // Add our backgrounds. 14 | normalImage.setNineSliceImage( 15 | Paths::TEXTURE_DIR + "MainButton/NormalThick.png", {4, 4, 4, 4}); 16 | hoveredImage.setNineSliceImage( 17 | Paths::TEXTURE_DIR + "MainButton/HoveredThick.png", {4, 4, 4, 4}); 18 | pressedImage.setNineSliceImage( 19 | Paths::TEXTURE_DIR + "MainButton/PressedThick.png", {4, 4, 4, 4}); 20 | disabledImage.setNineSliceImage( 21 | Paths::TEXTURE_DIR + "MainButton/DisabledThick.png", {4, 4, 4, 4}); 22 | 23 | // Set our text properties. 24 | text.setFont((Paths::FONT_DIR + "B612-Regular.ttf"), 33); 25 | text.setColor({255, 255, 255, 255}); 26 | text.setText(inText); 27 | } 28 | 29 | } // End namespace ResourceImporter 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/TitleScreen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Screen.h" 4 | #include "TitleWindow.h" 5 | 6 | namespace AM 7 | { 8 | namespace ResourceImporter 9 | { 10 | class UserInterface; 11 | class DataModel; 12 | 13 | /** 14 | * The opening title screen that you see on app launch. 15 | */ 16 | class TitleScreen : public AUI::Screen 17 | { 18 | public: 19 | TitleScreen(UserInterface& inUserInterface, DataModel& inDataModel); 20 | 21 | void render() override; 22 | 23 | private: 24 | //------------------------------------------------------------------------- 25 | // Windows 26 | //------------------------------------------------------------------------- 27 | TitleWindow titleWindow; 28 | }; 29 | 30 | } // End namespace ResourceImporter 31 | } // End namespace AM 32 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Widgets/LibraryCollapsibleContainer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/CollapsibleContainer.h" 4 | 5 | namespace AM 6 | { 7 | namespace ResourceImporter 8 | { 9 | /** 10 | * A collapsible container used for the top-level categories in the library 11 | * window on the main screen. 12 | */ 13 | class LibraryCollapsibleContainer : public AUI::CollapsibleContainer 14 | { 15 | public: 16 | LibraryCollapsibleContainer(const std::string& inHeaderText, 17 | const std::string& inDebugName 18 | = "LibraryCollapsibleContainer"); 19 | 20 | /** 21 | * Sets the left padding. Used to define the visual hierarchy in the list. 22 | */ 23 | void setLeftPadding(int inLeftPadding); 24 | }; 25 | 26 | } // End namespace ResourceImporter 27 | } // End namespace AM 28 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Widgets/MainButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Screen.h" 4 | #include "AUI/Button.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | /** 12 | * The usual button style used for the main screen. 13 | */ 14 | class MainButton : public AUI::Button 15 | { 16 | public: 17 | MainButton(const SDL_Rect& inLogicalExtent, const std::string& inText, 18 | const std::string& inDebugName = "MainButton"); 19 | }; 20 | 21 | } // End namespace ResourceImporter 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Widgets/MainTextInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/TextInput.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace ResourceImporter 9 | { 10 | /** 11 | * The text input style used for the main screen. 12 | */ 13 | class MainTextInput : public AUI::TextInput 14 | { 15 | public: 16 | MainTextInput(const SDL_Rect& inLogicalExtent, 17 | const std::string& inDebugName = "MainTextInput"); 18 | }; 19 | 20 | } // End namespace ResourceImporter 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Widgets/MainThumbnail.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Screen.h" 4 | #include "AUI/Thumbnail.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | /** 12 | * The thumbnail style used for the main screen. 13 | */ 14 | class MainThumbnail : public AUI::Thumbnail 15 | { 16 | public: 17 | MainThumbnail(const std::string& inDebugName = "MainThumbnail"); 18 | }; 19 | 20 | } // End namespace ResourceImporter 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Widgets/TitleButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Button.h" 4 | 5 | namespace AM 6 | { 7 | namespace ResourceImporter 8 | { 9 | /** 10 | * The button style used for the title screen. 11 | */ 12 | class TitleButton : public AUI::Button 13 | { 14 | public: 15 | TitleButton(const SDL_Rect& inLogicalExtent, const std::string& inText, 16 | const std::string& inDebugName = "TitleButton"); 17 | }; 18 | 19 | } // End namespace ResourceImporter 20 | } // End namespace AM 21 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Windows/HamburgerButtonWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Window.h" 4 | #include "AUI/Image.h" 5 | #include "AUI/Button.h" 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | class MainScreen; 12 | 13 | /** 14 | * Holds the "hamburger menu" button at the top of the screen, next to the 15 | * properties window. 16 | * 17 | * Facilitates file operations like saving the json, or exporting sprite 18 | * sheet images. 19 | */ 20 | class HamburgerButtonWindow : public AUI::Window 21 | { 22 | public: 23 | HamburgerButtonWindow(MainScreen& inScreen); 24 | 25 | private: 26 | /** Used to open the confirmation dialog. */ 27 | MainScreen& mainScreen; 28 | 29 | //------------------------------------------------------------------------- 30 | // Private child widgets 31 | //------------------------------------------------------------------------- 32 | AUI::Image backgroundImage; 33 | 34 | AUI::Button hamburgerButton; 35 | }; 36 | 37 | } // End namespace ResourceImporter 38 | } // End namespace AM 39 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Windows/HamburgerMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Window.h" 4 | #include "AUI/Image.h" 5 | #include "AUI/Button.h" 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | 12 | /** 13 | * A menu that lets the user perform file operations, like saving the json, or 14 | * exporting sprite sheet images 15 | * 16 | * Opens when you press the hamburger button. 17 | */ 18 | class HamburgerMenu : public AUI::Window 19 | { 20 | public: 21 | HamburgerMenu(); 22 | 23 | //------------------------------------------------------------------------- 24 | // Public child widgets 25 | //------------------------------------------------------------------------- 26 | /** The menu's background */ 27 | AUI::Image backgroundImage; 28 | 29 | AUI::Button saveButton; 30 | AUI::Button exportButton; 31 | 32 | //------------------------------------------------------------------------- 33 | // Base class overrides 34 | //------------------------------------------------------------------------- 35 | void onFocusLost(AUI::FocusLostType focusLostType) override; 36 | 37 | private: 38 | /** 39 | * Styles the given button and sets its text to the given text. 40 | */ 41 | void styleButton(AUI::Button& button, const std::string& text); 42 | }; 43 | 44 | } // End namespace ResourceImporter 45 | } // End namespace AM 46 | -------------------------------------------------------------------------------- /Source/ResourceImporter/UserInterface/Public/Windows/TitleWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AUI/Window.h" 4 | #include "AUI/Text.h" 5 | #include "TitleButton.h" 6 | 7 | namespace AM 8 | { 9 | namespace ResourceImporter 10 | { 11 | class UserInterface; 12 | class TitleScreen; 13 | class DataModel; 14 | 15 | /** 16 | * The single window for the title screen. 17 | */ 18 | class TitleWindow : public AUI::Window 19 | { 20 | public: 21 | TitleWindow(UserInterface& inUserInterface, DataModel& inDataModel); 22 | 23 | private: 24 | void onOpenButtonPressed(); 25 | 26 | /** Used for switching to the main screen. */ 27 | UserInterface& userInterface; 28 | /** Used for loading the user-selected file. */ 29 | DataModel& dataModel; 30 | 31 | //------------------------------------------------------------------------- 32 | // Private child widgets 33 | //------------------------------------------------------------------------- 34 | AUI::Text titleText; 35 | 36 | AUI::Text directionText; 37 | 38 | TitleButton openButton; 39 | 40 | AUI::Text errorText; 41 | }; 42 | 43 | } // End namespace ResourceImporter 44 | } // End namespace AM 45 | -------------------------------------------------------------------------------- /Source/ResourceImporter/Utility/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ResourceImporter 2 | PRIVATE 3 | Private/SpriteTools.cpp 4 | PUBLIC 5 | Public/SpriteTools.h 6 | ) 7 | 8 | target_include_directories(ResourceImporter 9 | PRIVATE 10 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 11 | PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 13 | ) 14 | -------------------------------------------------------------------------------- /Source/ServerLib/Config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ServerLib 2 | PRIVATE 3 | Private/UserConfig.cpp 4 | Private/UserConfigInitializer.cpp 5 | PUBLIC 6 | Public/UserConfig.h 7 | Public/UserConfigInitializer.h 8 | ) 9 | 10 | target_include_directories(ServerLib 11 | PRIVATE 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 13 | PUBLIC 14 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 15 | ) 16 | -------------------------------------------------------------------------------- /Source/ServerLib/Config/Private/UserConfig.cpp: -------------------------------------------------------------------------------- 1 | #include "UserConfig.h" 2 | #include "Paths.h" 3 | #include "Log.h" 4 | #include "nlohmann/json.hpp" 5 | #include 6 | #include 7 | 8 | namespace AM 9 | { 10 | namespace Server 11 | { 12 | 13 | UserConfig::UserConfig() 14 | { 15 | // Open the file. 16 | std::string fullPath{Paths::BASE_PATH}; 17 | fullPath += "UserConfig.json"; 18 | std::ifstream workingFile(fullPath); 19 | if (!(workingFile.is_open())) { 20 | LOG_FATAL("Failed to open UserConfig.json"); 21 | } 22 | 23 | // Parse the file into a json structure. 24 | nlohmann::json json; 25 | try { 26 | json = nlohmann::json::parse(workingFile, nullptr, true, true); 27 | } catch (nlohmann::json::exception& e) { 28 | LOG_FATAL("Failed to parse UserConfig.json: %s", e.what()); 29 | } 30 | 31 | // Initialize our members. 32 | try { 33 | init(json); 34 | } catch (nlohmann::json::exception& e) { 35 | LOG_FATAL("%s", e.what()); 36 | } 37 | } 38 | 39 | UserConfig& UserConfig::get() 40 | { 41 | static UserConfig userConfig; 42 | return userConfig; 43 | } 44 | 45 | void UserConfig::init([[maybe_unused]] nlohmann::json& json) {} 46 | 47 | } // End namespace Server 48 | } // End namespace AM 49 | -------------------------------------------------------------------------------- /Source/ServerLib/Config/Private/UserConfigInitializer.cpp: -------------------------------------------------------------------------------- 1 | #include "UserConfigInitializer.h" 2 | #include "UserConfig.h" 3 | 4 | namespace AM 5 | { 6 | namespace Server 7 | { 8 | UserConfigInitializer::UserConfigInitializer() 9 | { 10 | UserConfig::get(); 11 | } 12 | 13 | } // End namespace Server 14 | } // End namespace AM 15 | -------------------------------------------------------------------------------- /Source/ServerLib/Config/Public/UserConfigInitializer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Server 6 | { 7 | /** 8 | * Minimal helper class to facilitate calling UserConfig::get() from an 9 | * initializer list. 10 | */ 11 | class UserConfigInitializer 12 | { 13 | public: 14 | UserConfigInitializer(); 15 | }; 16 | 17 | } // End namespace Server 18 | } // End namespace AM 19 | -------------------------------------------------------------------------------- /Source/ServerLib/Launch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ServerLib 2 | PRIVATE 3 | Private/Application.cpp 4 | PUBLIC 5 | Public/Application.h 6 | ) 7 | 8 | target_include_directories(ServerLib 9 | PRIVATE 10 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 11 | PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 13 | ) 14 | -------------------------------------------------------------------------------- /Source/ServerLib/Network/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(ServerLib 2 | PRIVATE 3 | Private/Client.cpp 4 | Private/ClientHandler.cpp 5 | Private/MessageProcessor.cpp 6 | Private/Network.cpp 7 | Private/SDLNetInitializer.cpp 8 | PUBLIC 9 | Public/Client.h 10 | Public/ClientMap.h 11 | Public/ClientConnectionEvent.h 12 | Public/ClientHandler.h 13 | Public/IMessageProcessorExtension.h 14 | Public/MessageProcessor.h 15 | Public/MessageProcessorExDependencies.h 16 | Public/Network.h 17 | Public/SDLNetInitializer.h 18 | ) 19 | 20 | target_include_directories(ServerLib 21 | PRIVATE 22 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 23 | PUBLIC 24 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 25 | ) 26 | -------------------------------------------------------------------------------- /Source/ServerLib/Network/Private/SDLNetInitializer.cpp: -------------------------------------------------------------------------------- 1 | #include "SDLNetInitializer.h" 2 | #include "SDL_net.h" 3 | 4 | namespace AM 5 | { 6 | namespace Server 7 | { 8 | SDLNetInitializer::SDLNetInitializer() 9 | { 10 | SDLNet_Init(); 11 | } 12 | 13 | SDLNetInitializer::~SDLNetInitializer() 14 | { 15 | SDLNet_Quit(); 16 | } 17 | 18 | } // end namespace Server 19 | } // end namespace AM 20 | -------------------------------------------------------------------------------- /Source/ServerLib/Network/Public/ClientConnectionEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NetworkID.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Server 9 | { 10 | /** 11 | * Used to tell the simulation that a client was connected. 12 | */ 13 | struct ClientConnected { 14 | /** The ID of the client that connected. */ 15 | NetworkID clientID{0}; 16 | }; 17 | 18 | /** 19 | * Used to tell the simulation that a client was disconnected. 20 | */ 21 | struct ClientDisconnected { 22 | /** The ID of the client that disconnected. */ 23 | NetworkID clientID{0}; 24 | }; 25 | 26 | /** Used to synchronize connect/disconnect events. Without this, we may observe 27 | a disconnect for a client before processing the connect event. */ 28 | using ClientConnectionEvent 29 | = std::variant; 30 | 31 | } // End namespace Server 32 | } // End namespace AM 33 | -------------------------------------------------------------------------------- /Source/ServerLib/Network/Public/ClientMap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NetworkID.h" 4 | #include 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace Server 10 | { 11 | class Client; 12 | 13 | /** A map type used to manage clients. */ 14 | using ClientMap = std::unordered_map>; 15 | 16 | } // End namespace Server 17 | } // End namespace AM 18 | -------------------------------------------------------------------------------- /Source/ServerLib/Network/Public/MessageProcessorExDependencies.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | class EventDispatcher; 6 | 7 | namespace Server 8 | { 9 | 10 | /** 11 | * Defines the dependencies that will be provided to the project's 12 | * MessageProcessorExtension class. 13 | */ 14 | struct MessageProcessorExDependencies { 15 | public: 16 | EventDispatcher& networkEventDispatcher; 17 | }; 18 | 19 | } // namespace Server 20 | } // namespace AM 21 | -------------------------------------------------------------------------------- /Source/ServerLib/Network/Public/SDLNetInitializer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Server 6 | { 7 | /** 8 | * Minimal helper class to facilitate calling SDLNet_Init from an initializer 9 | * list. 10 | * 11 | * SDLNet_Init must be called after SDL is initialized, but before any SDLNet 12 | * functions are called. 13 | */ 14 | class SDLNetInitializer 15 | { 16 | public: 17 | SDLNetInitializer(); 18 | 19 | ~SDLNetInitializer(); 20 | }; 21 | 22 | } // End namespace Server 23 | } // End namespace AM 24 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Private/AISystem.cpp: -------------------------------------------------------------------------------- 1 | #include "AISystem.h" 2 | #include "World.h" 3 | #include "ProjectAITypes.h" 4 | #include "Log.h" 5 | #include "boost/mp11/algorithm.hpp" 6 | 7 | namespace AM 8 | { 9 | namespace Server 10 | { 11 | 12 | AISystem::AISystem(World& inWorld) 13 | : world{inWorld} 14 | { 15 | } 16 | 17 | void AISystem::processAITick() 18 | { 19 | // For each AI type in the list, update all AI components of that type. 20 | boost::mp11::mp_for_each( 21 | [&](auto I) { 22 | using AIType = decltype(I); 23 | 24 | auto view{world.registry.view()}; 25 | for (auto [entity, aiLogic] : view.each()) { 26 | aiLogic.tick(world, entity); 27 | } 28 | }); 29 | } 30 | 31 | } // End namespace Server 32 | } // End namespace AM 33 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Private/GraphicData/GraphicData.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphicData.h" 2 | 3 | namespace AM 4 | { 5 | namespace Server 6 | { 7 | GraphicData::GraphicData(const nlohmann::json& resourceDataJson) 8 | : GraphicDataBase(resourceDataJson) 9 | { 10 | } 11 | 12 | } // End namespace Server 13 | } // End namespace AM 14 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Private/IconData/IconData.cpp: -------------------------------------------------------------------------------- 1 | #include "IconData.h" 2 | 3 | namespace AM 4 | { 5 | namespace Server 6 | { 7 | IconData::IconData(const nlohmann::json& resourceDataJson) 8 | : IconDataBase(resourceDataJson) 9 | { 10 | } 11 | 12 | } // End namespace Server 13 | } // End namespace AM 14 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Private/MovementSystem.cpp: -------------------------------------------------------------------------------- 1 | #include "MovementSystem.h" 2 | #include "MovementHelpers.h" 3 | #include "World.h" 4 | #include "EnttGroups.h" 5 | #include "SharedConfig.h" 6 | #include "Transforms.h" 7 | #include "Log.h" 8 | #include "tracy/Tracy.hpp" 9 | 10 | namespace AM 11 | { 12 | namespace Server 13 | { 14 | MovementSystem::MovementSystem(World& inWorld) 15 | : world(inWorld) 16 | , entityMover{world.registry, world.tileMap, world.entityLocator, 17 | world.collisionLocator} 18 | { 19 | } 20 | 21 | void MovementSystem::processMovements() 22 | { 23 | ZoneScoped; 24 | 25 | // Move all entities that have the required components. 26 | auto movementGroup = EnttGroups::getMovementGroup(world.registry); 27 | for (auto [entity, input, position, previousPosition, movement, 28 | movementMods, rotation, collision] : movementGroup.each()) { 29 | // Save their old position. 30 | previousPosition = position; 31 | 32 | // Move the entity. 33 | entityMover.moveEntity(entity, input.inputStates, position, 34 | previousPosition, movement, movementMods, 35 | rotation, collision, 36 | SharedConfig::SIM_TICK_TIMESTEP_S); 37 | } 38 | } 39 | 40 | } // namespace Server 41 | } // namespace AM 42 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/AILogic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "entt/fwd.hpp" 4 | 5 | namespace AM 6 | { 7 | namespace Server 8 | { 9 | class World; 10 | 11 | /** 12 | * Interface class for entity AI logic. 13 | */ 14 | class AILogic 15 | { 16 | public: 17 | // Note: We pass world and entity as parameters so that we don't have to 18 | // deal with a World& member during serialization. 19 | /** 20 | * Processes one iteration of AI logic. 21 | * 22 | * If the given entity doesn't possess any of the necessary components, 23 | * prints a warning and returns early. 24 | * 25 | * @param entity The entity that this AI is controlling. 26 | */ 27 | virtual void tick(World& world, entt::entity entity) = 0; 28 | }; 29 | 30 | } // namespace Server 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/AISystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Server 6 | { 7 | 8 | class World; 9 | 10 | /** 11 | * Handles AI processing. 12 | */ 13 | class AISystem 14 | { 15 | public: 16 | AISystem(World& inWorld); 17 | 18 | /** 19 | * Calls tick() on all AI components. 20 | */ 21 | void processAITick(); 22 | 23 | private: 24 | /** Used to get AI components to process. */ 25 | World& world; 26 | }; 27 | 28 | } // End namespace Server 29 | } // End namespace AM 30 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Components/CastState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CastableID.h" 4 | #include "CastInfo.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace Server 10 | { 11 | 12 | /** 13 | * Tracks whether an entity is currently casting a Castable. 14 | * 15 | * To optimize performance, this component will only be present on an entity if 16 | * a cast is currently ongoing. It gets removed when the cast ends. 17 | * 18 | * Note: This is server-only because the client needs its own version to track 19 | * additional data. 20 | */ 21 | struct CastState { 22 | /** The current cast's info. */ 23 | CastInfo castInfo{}; 24 | 25 | /** The tick that this cast will finish on. If 0, this cast hasn't been 26 | processed for the first time yet. */ 27 | Uint32 endTick{}; 28 | }; 29 | 30 | } // namespace Server 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Components/ClientSimData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NetworkDefs.h" 4 | #include "entt/fwd.hpp" 5 | #include 6 | 7 | namespace AM 8 | { 9 | namespace Server 10 | { 11 | /** 12 | * Holds all client-related sim data. 13 | * 14 | * If you need to tell if an entity is a client entity or not, favor checking 15 | * for IsClientEntity over this. IsClientEntity gets replicated to the clients, 16 | * so it's more expected to see. 17 | */ 18 | struct ClientSimData { 19 | /** The network ID associated with this client. 20 | We track this here so the sim knows where to send messages related to 21 | the entity. 22 | We also use this to remove the entity from the sim when the Client 23 | disconnects.*/ 24 | NetworkID netID{0}; 25 | 26 | /** Tracks the entities that are in range of this client's entity. */ 27 | std::vector entitiesInAOI{}; 28 | }; 29 | 30 | } // namespace Server 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Components/ReplicatedComponentList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace AM 7 | { 8 | namespace Server 9 | { 10 | /** 11 | * Tracks which client-relevant components this entity currently has attached 12 | * to it. 13 | * 14 | * Client-relevant components are any that we need to replicate to the client, 15 | * e.g. Position. If the client doesn't care about it, it won't be tracked here. 16 | * 17 | * Note: This component will be present on an entity regardless of whether it 18 | * has any replicated components or not. This is because the on_destroy() 19 | * listener isn't allowed to remove components, so we just always leave 20 | * it. 21 | */ 22 | struct ReplicatedComponentList { 23 | /** Holds all currently attached component types that are relevant to 24 | the client. 25 | Each element refers to an index in the ReplicatedComponent variant. */ 26 | std::vector typeIndices; 27 | }; 28 | 29 | } // namespace Server 30 | } // namespace AM 31 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/EntityItemHandlerScript.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | namespace Server 8 | { 9 | /** 10 | * An entity's script to run when a particular item is used on it. 11 | * 12 | * Handler scripts are written as part of an entity's init script, through the 13 | * addItemHandler() lua function. 14 | */ 15 | struct EntityItemHandlerScript { 16 | /** Used as a "we should never hit this" cap on the length of the script 17 | string. */ 18 | static constexpr std::size_t MAX_LENGTH{10000}; 19 | 20 | /** The item handler script. */ 21 | std::string script{}; 22 | }; 23 | 24 | template 25 | void serialize(S& serializer, EntityItemHandlerScript& itemHandlerScript) 26 | { 27 | serializer.text1b(itemHandlerScript.script, 28 | EntityItemHandlerScript::MAX_LENGTH); 29 | } 30 | 31 | } // namespace Server 32 | } // namespace AM 33 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/EntityStoredValueID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * An entity stored value's numeric ID. 10 | * Note: Global stored values are handled separately. This file only applies 11 | * to values stored in an entity's StoredValues component. 12 | * 13 | * These IDs are created when a new string ID is first used, and are never 14 | * deleted. 15 | * Note: If we ever care to reclaim these values, we can write a function 16 | * that iterates the StoredValues components and removes any string IDs 17 | * from World::storedValueIDMap that aren't used. 18 | */ 19 | using EntityStoredValueID = Uint16; 20 | 21 | /** 22 | * The ID of the "null stored value", or the ID used to indicate that a 23 | * value is not present. 24 | * 25 | * Note: Since the null ID is 0, you can do null checks like "if (valueID)". 26 | */ 27 | static constexpr EntityStoredValueID NULL_ENTITY_STORED_VALUE_ID{0}; 28 | 29 | } // End namespace AM 30 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/GraphicData/GraphicData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicDataBase.h" 4 | 5 | namespace AM 6 | { 7 | namespace Server 8 | { 9 | /** 10 | * See GraphicDataBase class comment. 11 | * 12 | * The server doesn't currently do any parsing beyond what GraphicDataBase 13 | * performs, but this class exists to maintain a pattern consistent with 14 | * Client::GraphicData (which does do additional parsing). 15 | */ 16 | class GraphicData : public GraphicDataBase 17 | { 18 | public: 19 | /** 20 | * Calls GraphicDataBase() constructor. 21 | */ 22 | GraphicData(const nlohmann::json& resourceDataJson); 23 | }; 24 | 25 | } // End namespace Server 26 | } // End namespace AM 27 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/IconData/IconData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IconDataBase.h" 4 | 5 | namespace AM 6 | { 7 | namespace Server 8 | { 9 | /** 10 | * See IconDataBase class comment. 11 | * 12 | * The server doesn't currently do any parsing beyond what IconDataBase 13 | * performs, but this class exists to maintain a pattern consistent with 14 | * Client::IconData (which does do additional parsing). 15 | */ 16 | class IconData : public IconDataBase 17 | { 18 | public: 19 | /** 20 | * Calls IconDataBase() constructor. 21 | */ 22 | IconData(const nlohmann::json& resourceDataJson); 23 | }; 24 | 25 | } // End namespace Server 26 | } // End namespace AM 27 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/InputSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NetworkDefs.h" 4 | #include "QueuedEvents.h" 5 | #include "InputChangeRequest.h" 6 | #include "EventSorter.h" 7 | 8 | namespace AM 9 | { 10 | namespace Server 11 | { 12 | class Simulation; 13 | class World; 14 | class Network; 15 | 16 | /** 17 | * Receives input messages from clients and applies them to the client's 18 | * entity. 19 | */ 20 | class InputSystem 21 | { 22 | public: 23 | InputSystem(Simulation& inSimulation, World& inWorld, Network& inNetwork); 24 | 25 | /** 26 | * Processes incoming InputChangeRequest messages. 27 | */ 28 | void processInputMessages(); 29 | 30 | private: 31 | /** 32 | * Processes message drop events, which occur when the server received a 33 | * client's input message late and had to drop it. 34 | * 35 | * We default the client's inputs (so they don't run off a cliff) and set 36 | * a flag so the NetworkUpdateSystem knows that a drop occurred. 37 | * 38 | * @param clientID The ID of the client that we had to drop a message from. 39 | */ 40 | void handleDroppedMessage(NetworkID clientID); 41 | 42 | /** Used to get the current tick. */ 43 | Simulation& simulation; 44 | /** Used to access components. */ 45 | World& world; 46 | 47 | EventQueue inputChangeRequestQueue; 48 | EventSorter inputChangeRequestSorter; 49 | }; 50 | 51 | } // namespace Server 52 | } // namespace AM 53 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Lua/DialogueChoiceConditionLua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sol/sol.hpp" 4 | #include "entt/fwd.hpp" 5 | 6 | namespace AM 7 | { 8 | namespace Server 9 | { 10 | /** 11 | * The lua environment for running dialogue choice condition scripts. 12 | * 13 | * Condition scripts are much more limited than other dialogue scripts. They 14 | * only have access to getters, and will always be made into the form: 15 | * "r = (given script)" where r must hold a boolean type after evaluation. 16 | * 17 | * Contains additional members that are set by the script runner to pass 18 | * relevant data to the environment's bound functions. 19 | */ 20 | struct DialogueChoiceConditionLua { 21 | /** Lua environment for dialogue choice condition script processing. 22 | Global variables: 23 | "user": The ID of the entity that is controlling the dialogue. 24 | "self": The ID of the entity that is delivering the dialogue. 25 | "GLOBAL": A constant used to identify the global value store. */ 26 | sol::state luaState{}; 27 | 28 | /** The network ID of the client that is controlling the dialogue. */ 29 | NetworkID clientID{0}; 30 | }; 31 | 32 | } // namespace Server 33 | } // namespace AM 34 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Lua/DialogueLua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DialogueEvent.h" 4 | #include "NetworkID.h" 5 | #include "sol/sol.hpp" 6 | #include "entt/fwd.hpp" 7 | 8 | namespace AM 9 | { 10 | namespace Server 11 | { 12 | /** 13 | * The lua environment for running both dialogue topic scripts and dialogue 14 | * choice action scripts. 15 | * 16 | * Contains additional members that are set by the script runner to pass 17 | * relevant data to the environment's bound functions. 18 | */ 19 | struct DialogueLua { 20 | /** Lua environment for dialogue topic and choice action script 21 | processing. 22 | Global variables: 23 | "user": The ID of the entity that is controlling the dialogue. 24 | "self": The ID of the entity that is delivering the dialogue. 25 | "GLOBAL": A constant used to identify the global value store. */ 26 | sol::state luaState{}; 27 | 28 | /** The network ID of the client that is controlling the dialogue. */ 29 | NetworkID clientID{0}; 30 | 31 | /** (Out) The dialogue events that should be sent to the client. */ 32 | std::vector* dialogueEvents{}; 33 | 34 | /** (Out) The topic specified by the latest setNextTopic(). 35 | Will == "" if no setNextTopic() was called by the latest-ran script. */ 36 | std::string nextTopicName{""}; 37 | }; 38 | 39 | } // namespace Server 40 | } // namespace AM 41 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Lua/EntityInitLua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sol/sol.hpp" 4 | #include "entt/fwd.hpp" 5 | 6 | namespace AM 7 | { 8 | namespace Server 9 | { 10 | /** 11 | * The lua environment for running entity init scripts. 12 | * 13 | * Contains additional members that are set by the script runner to pass 14 | * relevant data to the environment's bound functions. 15 | */ 16 | struct EntityInitLua { 17 | /** Lua environment for entity init script processing. */ 18 | sol::state luaState{}; 19 | 20 | /** The entity that the init script is being ran on. */ 21 | entt::entity selfEntity{}; 22 | }; 23 | 24 | } // namespace Server 25 | } // namespace AM 26 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Lua/EntityItemHandlerLua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NetworkID.h" 4 | #include "sol/sol.hpp" 5 | #include "entt/fwd.hpp" 6 | 7 | namespace AM 8 | { 9 | namespace Server 10 | { 11 | /** 12 | * The lua environment for running entity item handler scripts. 13 | * 14 | * Contains additional members that are set by the script runner to pass 15 | * relevant data to the environment's bound functions. 16 | */ 17 | struct EntityItemHandlerLua { 18 | /** Lua environment for entity item handler script processing. 19 | Global variables: 20 | "user": The ID of the entity that used the item. 21 | May be a non-player entity. 22 | "self": The ID of the entity that the item is being used on. 23 | "GLOBAL": A constant used to identify the global value store. */ 24 | sol::state luaState{}; 25 | 26 | /** The network ID of the client that used the item. */ 27 | NetworkID clientID{0}; 28 | }; 29 | 30 | } // namespace Server 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/Lua/ItemInitLua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sol/sol.hpp" 4 | #include "entt/fwd.hpp" 5 | 6 | namespace AM 7 | { 8 | struct Item; 9 | 10 | namespace Server 11 | { 12 | 13 | /** 14 | * The lua environment for running item init scripts. 15 | * 16 | * Contains additional members that are set by the script runner to pass 17 | * relevant data to the environment's bound functions. 18 | */ 19 | struct ItemInitLua { 20 | /** Lua environment for item init script processing. */ 21 | sol::state luaState{}; 22 | 23 | /** The item that the init script is being ran on. 24 | Will always be non-nullptr. */ 25 | Item* selfItem{}; 26 | }; 27 | 28 | } // namespace Server 29 | } // namespace AM 30 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/MovementSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EntityMover.h" 4 | 5 | namespace AM 6 | { 7 | namespace Server 8 | { 9 | class World; 10 | 11 | /** 12 | * Moves entities. 13 | */ 14 | class MovementSystem 15 | { 16 | public: 17 | MovementSystem(World& inWorld); 18 | 19 | /** 20 | * Processes 1 tick of entity movement. 21 | */ 22 | void processMovements(); 23 | 24 | private: 25 | World& world; 26 | 27 | EntityMover entityMover; 28 | }; 29 | 30 | } // namespace Server 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/SimulationExDependencies.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | class CastableData; 6 | 7 | namespace Server 8 | { 9 | class Simulation; 10 | class Network; 11 | class GraphicData; 12 | class IconData; 13 | class ItemData; 14 | 15 | /** 16 | * Defines the dependencies that will be provided to the project's 17 | * SimulationExtension class. 18 | */ 19 | struct SimulationExDependencies { 20 | public: 21 | Simulation& simulation; 22 | 23 | Network& network; 24 | 25 | GraphicData& graphicData; 26 | 27 | IconData& iconData; 28 | 29 | ItemData& itemData; 30 | 31 | CastableData& castableData; 32 | }; 33 | 34 | } // namespace Server 35 | } // namespace AM 36 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/SpawnStrategy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace Server 6 | { 7 | 8 | /** 9 | * The strategies that we can use for determining where entities should spawn. 10 | */ 11 | enum class SpawnStrategy { 12 | /** Spawn in a fixed location. */ 13 | Fixed, 14 | /** Spawn in groups. */ 15 | Grouped, 16 | /** Spawn in a random location. */ 17 | Random 18 | }; 19 | 20 | } // namespace Server 21 | } // namespace AM 22 | -------------------------------------------------------------------------------- /Source/ServerLib/Simulation/Public/TypeLists/EngineObservedComponentTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Name.h" 4 | #include "MovementModifiers.h" 5 | #include "GraphicState.h" 6 | #include "Interaction.h" 7 | #include "boost/mp11/list.hpp" 8 | 9 | namespace AM 10 | { 11 | // Note: Observed components are server-only. 12 | namespace Server 13 | { 14 | /** 15 | * See EngineReplicatedComponentTypes.h for more info. 16 | */ 17 | using EngineObservedComponentTypes 18 | = boost::mp11::mp_list; 19 | 20 | } // End namespace Server 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/CastCooldownInit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include "CastCooldown.h" 5 | 6 | namespace AM 7 | { 8 | /** 9 | * Sent by the server when a client needs their full list of cast cooldowns. 10 | * After the full list is sent, the client can update it locally as casts are 11 | * completed. 12 | */ 13 | struct CastCooldownInit { 14 | // The MessageType enum value that this message corresponds to. 15 | // Declares this struct as a message that the Network can send and receive. 16 | static constexpr EngineMessageType MESSAGE_TYPE{ 17 | EngineMessageType::CastCooldownInit}; 18 | 19 | /** 20 | * The entity's full CastCooldown component. 21 | */ 22 | CastCooldown castCooldown{}; 23 | }; 24 | 25 | template 26 | void serialize(S& serializer, CastCooldownInit& castCooldownInit) 27 | { 28 | serializer.object(castCooldownInit.castCooldown); 29 | } 30 | 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/CastFailed.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include "CastableID.h" 5 | #include "CastFailureType.h" 6 | #include "entt/fwd.hpp" 7 | #include "entt/entity/entity.hpp" 8 | 9 | namespace AM 10 | { 11 | 12 | /** 13 | * Sent by the server when a cast either fails to validate, or is canceled. 14 | */ 15 | struct CastFailed { 16 | // The MessageType enum value that this message corresponds to. 17 | // Declares this struct as a message that the Network can send and receive. 18 | static constexpr EngineMessageType MESSAGE_TYPE{ 19 | EngineMessageType::CastFailed}; 20 | 21 | /** The entity that was casting. */ 22 | entt::entity casterEntity{entt::null}; 23 | 24 | /** The castable that was being cast. */ 25 | CastableID castableID{}; 26 | 27 | /** The reason why the cast failed. */ 28 | CastFailureType castFailureType{}; 29 | }; 30 | 31 | template 32 | void serialize(S& serializer, CastFailed& castFailed) 33 | { 34 | serializer.value4b(castFailed.casterEntity); 35 | serializer.object(castFailed.castableID); 36 | serializer.value1b(castFailed.castFailureType); 37 | } 38 | 39 | } // End namespace AM 40 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/ChunkUpdate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include "ChunkWireSnapshot.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | /** 10 | * Used by the server to stream chunks to a client. 11 | */ 12 | struct ChunkUpdate { 13 | public: 14 | // The EngineMessageType enum value that this message corresponds to. 15 | // Declares this struct as a message that the Network can send and receive. 16 | static constexpr EngineMessageType MESSAGE_TYPE{ 17 | EngineMessageType::ChunkUpdate}; 18 | 19 | /** Used as a "we should never hit this" cap on the number of chunks that 20 | we request at once. 9 is for the current chunk and all surrounding chunks 21 | in the X/Y directions, 20 is a large number to cap how many levels the 22 | map can have in the Z direction. */ 23 | static constexpr std::size_t MAX_CHUNKS{9 * 20}; 24 | 25 | /** The chunks that the client should load. */ 26 | std::vector chunks; 27 | }; 28 | 29 | template 30 | void serialize(S& serializer, ChunkUpdate& chunkUpdate) 31 | { 32 | serializer.container(chunkUpdate.chunks, ChunkUpdate::MAX_CHUNKS); 33 | } 34 | 35 | } // End namespace AM 36 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/ConnectionRequest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * Contains a connection response, sent from the server to the client. 10 | */ 11 | struct ConnectionRequest { 12 | // The EngineMessageType enum value that this message corresponds to. 13 | // Declares this struct as a message that the Network can send and receive. 14 | static constexpr EngineMessageType MESSAGE_TYPE{ 15 | EngineMessageType::ConnectionRequest}; 16 | 17 | /** Used as a "we should never hit this" cap on the size of each name 18 | string. */ 19 | static constexpr std::size_t MAX_NAME_LENGTH{50}; 20 | 21 | // Note: This will eventually change to login credentials and will be sent 22 | // to the login server instead of the simulation server. 23 | /** The name of this player. */ 24 | std::string playerName{""}; 25 | }; 26 | 27 | template 28 | void serialize(S& serializer, ConnectionRequest& connectionResponse) 29 | { 30 | serializer.text1b(connectionResponse.playerName, 31 | ConnectionRequest::MAX_NAME_LENGTH); 32 | } 33 | 34 | } // End namespace AM 35 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/EntityDelete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include "entt/fwd.hpp" 5 | #include "entt/entity/entity.hpp" 6 | 7 | namespace AM 8 | { 9 | /** 10 | * Used to request that an entity be deleted, or to inform a client that an 11 | * entity was deleted. 12 | */ 13 | struct EntityDelete { 14 | // The EngineMessageType enum value that this message corresponds to. 15 | // Declares this struct as a message that the Network can send and receive. 16 | static constexpr EngineMessageType MESSAGE_TYPE{ 17 | EngineMessageType::EntityDelete}; 18 | 19 | /** The tick that this update corresponds to. */ 20 | Uint32 tickNum{0}; 21 | 22 | /** The entity that must be deleted. */ 23 | entt::entity entity{entt::null}; 24 | }; 25 | 26 | template 27 | void serialize(S& serializer, EntityDelete& entityDelete) 28 | { 29 | serializer.value4b(entityDelete.tickNum); 30 | serializer.value4b(entityDelete.entity); 31 | } 32 | 33 | } // End namespace AM 34 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/ExplicitConfirmation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * An explicit confirmation that ticks have passed. 10 | * 11 | * Sent from Server -> Client when a tick passes with no entity movement 12 | * updates. The client needs these confirmations before it can progress 13 | * NPC movement forward. 14 | */ 15 | struct ExplicitConfirmation { 16 | // The EngineMessageType enum value that this message corresponds to. 17 | // Declares this struct as a message that the Network can send and receive. 18 | static constexpr EngineMessageType MESSAGE_TYPE{ 19 | EngineMessageType::ExplicitConfirmation}; 20 | 21 | Uint8 confirmedTickCount{0}; 22 | }; 23 | 24 | template 25 | void serialize(S& serializer, ExplicitConfirmation& explicitConfirmation) 26 | { 27 | serializer.value1b(explicitConfirmation.confirmedTickCount); 28 | } 29 | 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/Heartbeat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * A heartbeat is sent from either side to show that a tick was processed but 10 | * no data needed to be sent. 11 | */ 12 | struct Heartbeat { 13 | // The EngineMessageType enum value that this message corresponds to. 14 | // Declares this struct as a message that the Network can send and receive. 15 | static constexpr EngineMessageType MESSAGE_TYPE{ 16 | EngineMessageType::Heartbeat}; 17 | 18 | /** The tick that this heartbeat was processed on. */ 19 | Uint32 tickNum{0}; 20 | }; 21 | 22 | template 23 | void serialize(S& serializer, Heartbeat& heartbeat) 24 | { 25 | serializer.value4b(heartbeat.tickNum); 26 | } 27 | 28 | } // End namespace AM 29 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/InventoryMoveItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include "NetworkDefs.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | /** 10 | * Sent by a client to request that an item be moved to a different slot in 11 | * their inventory, or by the server to tell a client that an item was moved. 12 | * 13 | * Moving an item into an occupied slot swaps its position with the other item. 14 | */ 15 | struct InventoryMoveItem { 16 | /** The inventory slot of the item to move. */ 17 | Uint8 sourceSlotIndex{0}; 18 | 19 | /** The inventory slot to move the item into (destination). */ 20 | Uint8 destSlotIndex{0}; 21 | }; 22 | 23 | template 24 | void serialize(S& serializer, InventoryMoveItem& inventoryMoveItem) 25 | { 26 | serializer.value1b(inventoryMoveItem.sourceSlotIndex); 27 | serializer.value1b(inventoryMoveItem.destSlotIndex); 28 | } 29 | 30 | } // namespace AM 31 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/InventoryRemoveItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include "ItemID.h" 5 | #include "NetworkDefs.h" 6 | #include 7 | 8 | namespace AM 9 | { 10 | /** 11 | * Sent by a client to request that an item be removed from an inventory, or by 12 | * the server to tell a client that an item was removed. 13 | * 14 | * Note: This is currently only used for player inventories. If we reuse it for 15 | * NPC inventories, we can add an entity ID field. 16 | */ 17 | struct InventoryRemoveItem { 18 | /** The inventory slot to remove the item from. */ 19 | Uint8 slotIndex{0}; 20 | 21 | /** How many of the item to delete. */ 22 | Uint8 count{0}; 23 | }; 24 | 25 | template 26 | void serialize(S& serializer, InventoryRemoveItem& inventoryRemoveItem) 27 | { 28 | serializer.value1b(inventoryRemoveItem.slotIndex); 29 | serializer.value1b(inventoryRemoveItem.count); 30 | } 31 | 32 | } // namespace AM 33 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/MovementState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Input.h" 4 | #include "Position.h" 5 | #include "Movement.h" 6 | #include "MovementModifiers.h" 7 | #include "entt/entity/registry.hpp" 8 | 9 | namespace AM 10 | { 11 | /** 12 | * Contains movement state data for a single entity. 13 | * 14 | * Used for sending movement state updates to clients. 15 | */ 16 | struct MovementState { 17 | /** The entity that this state belongs to. */ 18 | entt::entity entity{entt::null}; 19 | 20 | Input input{}; 21 | Position position{}; 22 | Movement movement{}; 23 | MovementModifiers movementMods{}; 24 | 25 | // Note: Rotation is calculated client-side. 26 | }; 27 | 28 | template 29 | void serialize(S& serializer, MovementState& movementState) 30 | { 31 | serializer.value4b(movementState.entity); 32 | serializer.object(movementState.input); 33 | serializer.object(movementState.position); 34 | serializer.object(movementState.movement); 35 | serializer.object(movementState.movementMods); 36 | } 37 | 38 | } // End namespace AM 39 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/MovementUpdate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MovementState.h" 4 | #include "EngineMessageType.h" 5 | #include "SharedConfig.h" 6 | #include 7 | #include 8 | 9 | namespace AM 10 | { 11 | /** 12 | * Sent by the server when an entity moves and must have its state updated. 13 | * 14 | * Contains all updated entity movement state for a single sim tick. 15 | * 16 | * Each client is only sent the state of entities that are in their area of 17 | * interest. 18 | */ 19 | struct MovementUpdate { 20 | // The EngineMessageType enum value that this message corresponds to. 21 | // Declares this struct as a message that the Network can send and receive. 22 | static constexpr EngineMessageType MESSAGE_TYPE{ 23 | EngineMessageType::MovementUpdate}; 24 | 25 | /** The tick that this update corresponds to. */ 26 | Uint32 tickNum{0}; 27 | 28 | /** The new state of all relevant entities that updated on this tick. */ 29 | std::vector movementStates{}; 30 | }; 31 | 32 | template 33 | void serialize(S& serializer, MovementUpdate& movementUpdate) 34 | { 35 | serializer.value4b(movementUpdate.tickNum); 36 | serializer.container(movementUpdate.movementStates, 37 | SharedConfig::MAX_ENTITIES); 38 | } 39 | 40 | } // End namespace AM 41 | -------------------------------------------------------------------------------- /Source/SharedLib/Messages/Public/SystemMessage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineMessageType.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * A message sent by the server, intended to show up in a client's chat window. 10 | * 11 | * Used for various things, such as to tell a player "You must be closer to do 12 | * that." when they try to interact with something. 13 | */ 14 | struct SystemMessage { 15 | // The EngineMessageType enum value that this message corresponds to. 16 | // Declares this struct as a message that the Network can send and receive. 17 | static constexpr EngineMessageType MESSAGE_TYPE{ 18 | EngineMessageType::SystemMessage}; 19 | 20 | /** Used as a "we should never hit this" cap on the length of the error 21 | string. */ 22 | static constexpr std::size_t MAX_LENGTH{500}; 23 | 24 | /** The message string to display to the user. */ 25 | std::string messageString{}; 26 | }; 27 | 28 | template 29 | void serialize(S& serializer, SystemMessage& systemMessage) 30 | { 31 | serializer.text1b(systemMessage.messageString, SystemMessage::MAX_LENGTH); 32 | } 33 | 34 | } // End namespace AM 35 | -------------------------------------------------------------------------------- /Source/SharedLib/Network/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(SharedLib 2 | PRIVATE 3 | Private/Acceptor.cpp 4 | Private/Peer.cpp 5 | Private/SocketSet.cpp 6 | Private/TcpSocket.cpp 7 | Private/NetworkStats.cpp 8 | PUBLIC 9 | Public/Acceptor.h 10 | Public/DispatchMessage.h 11 | Public/NetworkDefs.h 12 | Public/NetworkID.h 13 | Public/Peer.h 14 | Public/SocketSet.h 15 | Public/TcpSocket.h 16 | Public/NetworkStats.h 17 | ) 18 | 19 | target_include_directories(SharedLib 20 | PRIVATE 21 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 22 | PUBLIC 23 | ${CMAKE_CURRENT_SOURCE_DIR}/Public 24 | ) 25 | -------------------------------------------------------------------------------- /Source/SharedLib/Network/Private/Acceptor.cpp: -------------------------------------------------------------------------------- 1 | #include "Acceptor.h" 2 | #include "Log.h" 3 | 4 | namespace AM 5 | { 6 | Acceptor::Acceptor(Uint16 port, const std::shared_ptr& inClientSet) 7 | : socket{} 8 | , listenerSet{1} 9 | , clientSet{inClientSet} 10 | { 11 | socket.openAsListener(port); 12 | listenerSet.addSocket(socket); 13 | } 14 | 15 | Acceptor::~Acceptor() {} 16 | 17 | std::unique_ptr Acceptor::accept() 18 | { 19 | listenerSet.checkSockets(0); 20 | 21 | if (socket.isReady()) { 22 | TcpSocket newSocket{socket.accept()}; 23 | if (newSocket.isOpen()) { 24 | return std::make_unique(std::move(newSocket), clientSet); 25 | } 26 | else { 27 | LOG_FATAL("Listener socket showed ready, but accept() failed."); 28 | } 29 | } 30 | 31 | return nullptr; 32 | } 33 | 34 | bool Acceptor::reject() 35 | { 36 | listenerSet.checkSockets(0); 37 | 38 | bool peerWasWaiting{false}; 39 | if (socket.isReady()) { 40 | TcpSocket newSocket{socket.accept()}; 41 | if (newSocket.isOpen()) { 42 | newSocket.close(); 43 | peerWasWaiting = true; 44 | } 45 | else { 46 | LOG_FATAL("Listener socket showed ready, but accept() failed."); 47 | } 48 | } 49 | 50 | return peerWasWaiting; 51 | } 52 | 53 | } // namespace AM 54 | -------------------------------------------------------------------------------- /Source/SharedLib/Network/Private/NetworkStats.cpp: -------------------------------------------------------------------------------- 1 | #include "NetworkStats.h" 2 | 3 | namespace AM 4 | { 5 | // Initialize data. 6 | std::atomic NetworkStats::bytesSent = 0; 7 | std::atomic NetworkStats::bytesReceived = 0; 8 | 9 | NetStatsDump NetworkStats::dumpStats() 10 | { 11 | // Fill the dump object while resetting the tracked values. 12 | NetStatsDump netStatsDump; 13 | 14 | netStatsDump.bytesSent = bytesSent.exchange(0); 15 | netStatsDump.bytesReceived = bytesReceived.exchange(0); 16 | 17 | return netStatsDump; 18 | } 19 | 20 | void NetworkStats::recordBytesSent(std::size_t inBytesSent) 21 | { 22 | bytesSent += inBytesSent; 23 | } 24 | 25 | void NetworkStats::recordBytesReceived(std::size_t inBytesReceived) 26 | { 27 | bytesReceived += inBytesReceived; 28 | } 29 | 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/SharedLib/Network/Private/SocketSet.cpp: -------------------------------------------------------------------------------- 1 | #include "SocketSet.h" 2 | #include "TcpSocket.h" 3 | #include "Log.h" 4 | 5 | namespace AM 6 | { 7 | SocketSet::SocketSet(int maxSockets) 8 | : numSockets(0) 9 | { 10 | set = SDLNet_AllocSocketSet(maxSockets); 11 | if (set == nullptr) { 12 | LOG_FATAL("Error allocating socket set: %s", SDLNet_GetError()); 13 | } 14 | } 15 | 16 | SocketSet::~SocketSet() 17 | { 18 | SDLNet_FreeSocketSet(set); 19 | set = nullptr; 20 | } 21 | 22 | void SocketSet::addSocket(const TcpSocket& socket) 23 | { 24 | int numAdded{SDLNet_TCP_AddSocket(set, socket.getUnderlyingSocket())}; 25 | if (numAdded < 1) { 26 | LOG_FATAL("Error while adding socket: %s", SDLNet_GetError()); 27 | } 28 | else { 29 | numSockets += numAdded; 30 | } 31 | } 32 | 33 | void SocketSet::remSocket(const TcpSocket& socket) 34 | { 35 | SDLNet_TCP_DelSocket(set, socket.getUnderlyingSocket()); 36 | } 37 | 38 | int SocketSet::checkSockets(unsigned int timeoutMs) 39 | { 40 | int numReady{SDLNet_CheckSockets(set, timeoutMs)}; 41 | if (numReady == -1) { 42 | LOG_FATAL("Error while checking sockets: %s", SDLNet_GetError()); 43 | // Most of the time this is a system error, where perror might help. 44 | perror("SDLNet_CheckSockets"); 45 | } 46 | 47 | return numReady; 48 | } 49 | 50 | } // End namespace AM 51 | -------------------------------------------------------------------------------- /Source/SharedLib/Network/Public/Acceptor.h: -------------------------------------------------------------------------------- 1 | #ifndef ACCEPTOR_H_ 2 | #define ACCEPTOR_H_ 3 | 4 | #include "Peer.h" 5 | #include "SocketSet.h" 6 | #include "TcpSocket.h" 7 | #include 8 | #include 9 | #include 10 | 11 | namespace AM 12 | { 13 | /** 14 | * Owns a listener socket and provides an interface for accepting new Peers. 15 | */ 16 | class Acceptor 17 | { 18 | public: 19 | Acceptor(Uint16 port, const std::shared_ptr& inClientSet); 20 | 21 | ~Acceptor(); 22 | 23 | /** 24 | * If a peer is waiting to connect, opens a connection to the peer and 25 | * adds it to the clientSet. 26 | * 27 | * @return A pointer to a new peer, if one was waiting. Else, nullptr. 28 | */ 29 | std::unique_ptr accept(); 30 | 31 | /** 32 | * If a peer is waiting to connect, opens a connection to the peer and 33 | * immediately closes it. 34 | * 35 | * Use this to close connections when you're at maximum capacity. 36 | * 37 | * @return true if a peer was waiting, else false. 38 | */ 39 | bool reject(); 40 | 41 | private: 42 | /** Our listener socket. */ 43 | TcpSocket socket; 44 | 45 | /** The set that we use to check if our socket has activity. */ 46 | SocketSet listenerSet; 47 | 48 | /** A pointer to the set to add accepted clients to. */ 49 | std::shared_ptr clientSet; 50 | }; 51 | 52 | } /* End namespace AM */ 53 | 54 | #endif /* End ACCEPTOR_H_ */ 55 | -------------------------------------------------------------------------------- /Source/SharedLib/Network/Public/NetworkID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** A numeric ID used to locally identify a client socket. 9 | Note: This is only used locally by the server, but it lives in Shared 10 | because it's convenient to use it in some shared code, e.g. message 11 | definitions (so that we can use one struct on both sides). */ 12 | using NetworkID = Uint16; 13 | 14 | /** 15 | * The ID used to indicate that a client is not present. 16 | * 17 | * Note: Since the null ID is 0, you can do null checks like "if (networkID)". 18 | */ 19 | static constexpr NetworkID NULL_NETWORK_ID{0}; 20 | 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/CastableData/Castable.cpp: -------------------------------------------------------------------------------- 1 | #include "Castable.h" 2 | #include "SharedConfig.h" 3 | 4 | namespace AM 5 | { 6 | 7 | Cylinder Castable::getTargetCylinder(const Vector3& position) const 8 | { 9 | static constexpr float HALF_HEIGHT{ 10 | SharedConfig::CAST_TARGET_CYLINDER_HALF_HEIGHT}; 11 | 12 | Cylinder targetCylinder{position, radius, HALF_HEIGHT}; 13 | targetCylinder.center.z -= HALF_HEIGHT; 14 | 15 | return targetCylinder; 16 | } 17 | 18 | bool Castable::hasVisuals() const 19 | { 20 | bool hasCastingGraphic{castingGraphicType != EntityGraphicType::NotSet}; 21 | bool hasCastCompleteGraphic{castCompleteGraphicType 22 | != EntityGraphicType::NotSet}; 23 | bool hasVisualEffect{castCompleteVisualEffects.size() != 0}; 24 | bool hasAVEntity{castCompleteAVEntities.size() != 0}; 25 | 26 | return hasCastingGraphic || hasCastCompleteGraphic || hasVisualEffect 27 | || hasAVEntity; 28 | } 29 | 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/Components/Camera.cpp: -------------------------------------------------------------------------------- 1 | #include "Camera.h" 2 | #include "Transforms.h" 3 | #include "SharedConfig.h" 4 | 5 | namespace AM 6 | { 7 | 8 | TileExtent Camera::getTileViewExtent(const TileExtent& mapTileExtent) const 9 | { 10 | TileExtent tileViewExtent(viewBounds); 11 | 12 | // Clip the view to the tile map's bounds. 13 | return tileViewExtent.intersectWith(mapTileExtent); 14 | } 15 | 16 | } // End namespace AM 17 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/Components/Interaction.cpp: -------------------------------------------------------------------------------- 1 | #include "Interaction.h" 2 | #include "SharedConfig.h" 3 | #include "Log.h" 4 | #include "AMAssert.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | 10 | bool Interaction::add(EntityInteractionType newInteraction) 11 | { 12 | if (supportedInteractions.size() 13 | == SharedConfig::MAX_ENTITY_INTERACTIONS) { 14 | // The interaction limit has been reached. 15 | return false; 16 | } 17 | else if (std::ranges::find(supportedInteractions, newInteraction) 18 | != supportedInteractions.end()) { 19 | // The interaction is already present. 20 | return false; 21 | } 22 | 23 | supportedInteractions.emplace_back(newInteraction); 24 | return true; 25 | } 26 | 27 | bool Interaction::supports(EntityInteractionType desiredInteraction) const 28 | { 29 | return (std::ranges::find(supportedInteractions, desiredInteraction) 30 | != supportedInteractions.end()); 31 | } 32 | 33 | EntityInteractionType Interaction::getDefault() const 34 | { 35 | AM_ASSERT(supportedInteractions.size() > 0, 36 | "Interaction component should never be empty."); 37 | return supportedInteractions[0]; 38 | } 39 | 40 | } // End namespace AM 41 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/Cylinder.cpp: -------------------------------------------------------------------------------- 1 | #include "Cylinder.h" 2 | #include "Position.h" 3 | #include "BoundingBox.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | bool Cylinder::intersects(const Position& position) const 10 | { 11 | // If the cylinder doesn't intersect along the Z axis, return false. 12 | float cylinderMinZ{center.z - halfHeight}; 13 | float cylinderMaxZ{center.z + halfHeight}; 14 | if ((position.z < cylinderMinZ) || (position.z > cylinderMaxZ)) { 15 | return false; 16 | } 17 | 18 | // The point intersects along the Z axis. The rest of the test now 19 | // reduces to a 2D circle/rectangle intersection. 20 | 21 | // Calc the X/Y components of the distance from our center to the point. 22 | float distanceX{std::abs(center.x - position.x)}; 23 | float distanceY{std::abs(center.y - position.y)}; 24 | 25 | // Calc the distance. Keep it squared to avoid a sqrt. 26 | float distanceSquared{(distanceX * distanceX) + (distanceY * distanceY)}; 27 | 28 | return (distanceSquared <= (radius * radius)); 29 | } 30 | 31 | bool Cylinder::intersects(const BoundingBox& boundingBox) const 32 | { 33 | return boundingBox.intersects(*this); 34 | } 35 | 36 | void Cylinder::print() const 37 | { 38 | LOG_INFO("(%.4f, %.4f, %.4f), %.4f, %.4f", center.x, center.y, center.z, 39 | radius, halfHeight); 40 | } 41 | 42 | } // End namespace AM 43 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/GraphicData/GraphicID.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphicID.h" 2 | 3 | namespace AM 4 | { 5 | 6 | bool isSpriteID(GraphicID graphicID) 7 | { 8 | return !((static_cast(graphicID) & GRAPHIC_ID_TYPE_MASK) >> 31); 9 | } 10 | 11 | bool isAnimationID(GraphicID graphicID) 12 | { 13 | return ((static_cast(graphicID) & GRAPHIC_ID_TYPE_MASK) >> 31); 14 | } 15 | 16 | SpriteID toSpriteID(GraphicID graphicID) 17 | { 18 | if (!isSpriteID(graphicID)) { 19 | return NULL_SPRITE_ID; 20 | } 21 | 22 | return (static_cast(graphicID) & GRAPHIC_ID_VALUE_MASK); 23 | } 24 | 25 | AnimationID toAnimationID(GraphicID graphicID) 26 | { 27 | if (!isAnimationID(graphicID)) { 28 | return NULL_ANIMATION_ID; 29 | } 30 | 31 | return (static_cast(graphicID) & GRAPHIC_ID_VALUE_MASK); 32 | } 33 | 34 | GraphicID toGraphicID(SpriteID spriteID) 35 | { 36 | // Sprite IDs don't need any special changes. 37 | return static_cast(spriteID); 38 | } 39 | 40 | GraphicID toGraphicID(AnimationID animationID) 41 | { 42 | // Set the top bit to indicate that this is an animation. 43 | return static_cast(animationID | GRAPHIC_ID_ANIMATION_VALUE); 44 | } 45 | 46 | } // End namespace AM 47 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/GraphicData/GraphicSets.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphicSets.h" 2 | #include "Log.h" 3 | #include "AMAssert.h" 4 | 5 | namespace AM 6 | { 7 | 8 | BoundingBox EntityGraphicSet::getCollisionModelBounds() const 9 | { 10 | // Note: Every entity graphic set must have a valid Idle. 11 | AM_ASSERT(graphics.contains(EntityGraphicType::Idle), 12 | "Entity graphic set is missing Idle: %s.", displayName.c_str()); 13 | 14 | const auto& idleGraphicArray{graphics.at(EntityGraphicType::Idle)}; 15 | const GraphicRef& idleSouthGraphicRef{ 16 | idleGraphicArray[Rotation::Direction::South]}; 17 | return idleSouthGraphicRef.getModelBounds(); 18 | } 19 | 20 | bool EntityGraphicSet::contains(EntityGraphicType type, 21 | Rotation::Direction direction) const 22 | { 23 | auto it{graphics.find(type)}; 24 | if (it != graphics.end()) { 25 | return (it->second.at(direction).getGraphicID() != NULL_GRAPHIC_ID); 26 | } 27 | 28 | return false; 29 | } 30 | 31 | } // End namespace AM 32 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/Ray.cpp: -------------------------------------------------------------------------------- 1 | #include "Ray.h" 2 | #include "Log.h" 3 | 4 | namespace AM 5 | { 6 | 7 | Vector3 Ray::getPointAtT(float t) 8 | { 9 | return {(origin.x + (direction.x * t)), (origin.y + (direction.y * t)), 10 | (origin.z + (direction.z * t))}; 11 | } 12 | 13 | void Ray::print() const 14 | { 15 | LOG_INFO("Origin: (%.4f, %.4f, %.4f), Direction: (%.4f, %.4f, %.4f)", 16 | origin.x, origin.y, origin.z, direction.x, direction.y, 17 | direction.z); 18 | } 19 | 20 | } // End namespace AM 21 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/ResourceData.cpp: -------------------------------------------------------------------------------- 1 | #include "ResourceData.h" 2 | #include "Paths.h" 3 | #include "Log.h" 4 | #include "nlohmann/json.hpp" 5 | #include 6 | 7 | namespace AM 8 | { 9 | 10 | ResourceData::ResourceData() 11 | { 12 | // Open the file. 13 | std::string fullPath{Paths::BASE_PATH}; 14 | fullPath += "ResourceData.json"; 15 | std::ifstream workingFile(fullPath); 16 | if (!(workingFile.is_open())) { 17 | LOG_FATAL("Failed to open ResourceData.json"); 18 | } 19 | 20 | // Parse the file into a json structure. 21 | try { 22 | resourceDataJson = std::make_unique( 23 | nlohmann::json::parse(workingFile, nullptr, true)); 24 | } catch (nlohmann::json::exception& e) { 25 | LOG_FATAL("Failed to parse ResourceData.json: %s", e.what()); 26 | } 27 | } 28 | 29 | ResourceData::~ResourceData() = default; 30 | 31 | nlohmann::json& ResourceData::get() 32 | { 33 | if (!resourceDataJson) { 34 | LOG_FATAL("Tried to get uninitialized json object."); 35 | } 36 | 37 | return *resourceDataJson; 38 | } 39 | 40 | } // End namespace AM 41 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/TileMap/Chunk.cpp: -------------------------------------------------------------------------------- 1 | #include "Chunk.h" 2 | #include "Morton.h" 3 | #include "AMAssert.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | Tile& Chunk::getTile(Uint16 tileOffsetX, Uint16 tileOffsetY) 10 | { 11 | AM_ASSERT(tileOffsetX < tiles.size(), "Invalid tile offset."); 12 | AM_ASSERT(tileOffsetY < tiles.size(), "Invalid tile offset."); 13 | return tiles[mortonEncode(tileOffsetX, tileOffsetY)]; 14 | } 15 | 16 | const Tile& Chunk::getTile(Uint16 tileOffsetX, Uint16 tileOffsetY) const 17 | { 18 | AM_ASSERT(tileOffsetX < tiles.size(), "Invalid tile offset."); 19 | AM_ASSERT(tileOffsetY < tiles.size(), "Invalid tile offset."); 20 | return tiles[mortonEncode(tileOffsetX, tileOffsetY)]; 21 | } 22 | 23 | Uint32 Chunk::mortonEncode(Uint16 x, Uint16 y) const 24 | { 25 | // If x and y fit in our lookup table, use it. Otherwise, calculate it 26 | // at runtime. 27 | if constexpr (SharedConfig::CHUNK_WIDTH <= 16) { 28 | return Morton::encode16x16(static_cast(x), 29 | static_cast(y)); 30 | } 31 | else { 32 | return Morton::encode32(x, y); 33 | } 34 | } 35 | 36 | } // End namespace AM 37 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/TileMap/Floor.cpp: -------------------------------------------------------------------------------- 1 | #include "Floor.h" 2 | #include "TilePosition.h" 3 | #include "Position.h" 4 | #include "SharedConfig.h" 5 | #include "AMAssert.h" 6 | 7 | namespace AM 8 | { 9 | static constexpr float WIDTH{SharedConfig::TILE_WORLD_WIDTH}; 10 | 11 | /** World-space bounding boxes for each terrain height. */ 12 | static constexpr BoundingBox FLOOR_BOX{{0, 0, 0}, {WIDTH, WIDTH, 0}}; 13 | 14 | BoundingBox Floor::calcWorldBounds(const TilePosition& tilePosition) 15 | { 16 | // Move the bounds to the tile's origin. 17 | Vector3 tileOrigin{tilePosition.getOriginPoint()}; 18 | return FLOOR_BOX.translateBy(tileOrigin); 19 | } 20 | 21 | } // End namespace AM 22 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Private/TileMap/TileLayer.cpp: -------------------------------------------------------------------------------- 1 | #include "TileLayer.h" 2 | #include "GraphicSets.h" 3 | #include "AMAssert.h" 4 | 5 | namespace AM 6 | { 7 | 8 | GraphicRef TileLayer::getGraphic() const 9 | { 10 | return getGraphic(type, graphicSet, graphicValue); 11 | } 12 | 13 | GraphicRef TileLayer::getGraphic(Type type, const GraphicSet& graphicSet, 14 | Uint8 graphicValue) 15 | { 16 | // Note: We don't need to check if the slots refer to a non-null 17 | // graphic, because the null graphic is fine to return. 18 | if (type == Type::Terrain) { 19 | Terrain::Height height{Terrain::getHeight(graphicValue)}; 20 | return static_cast(graphicSet) 21 | .graphics[height]; 22 | } 23 | else if (type == Type::Floor) { 24 | return static_cast(graphicSet) 25 | .graphics[graphicValue]; 26 | } 27 | else if (type == Type::Wall) { 28 | return static_cast(graphicSet) 29 | .graphics[graphicValue]; 30 | } 31 | else { 32 | // Type::Object 33 | return static_cast(graphicSet) 34 | .graphics[graphicValue]; 35 | } 36 | } 37 | 38 | } // End namespace AM 39 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/BoundingBoxID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** A bounding box's numeric ID. */ 9 | using BoundingBoxID = Uint16; 10 | 11 | /** 12 | * The ID used to indicate that a bounding box is not present. 13 | * 14 | * Note: Since the null ID is 0, you can do null checks like 15 | * "if (boundingBoxID)". 16 | */ 17 | static constexpr BoundingBoxID NULL_BOUNDING_BOX_ID{0}; 18 | 19 | } // End namespace AM 20 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/CastableData/AVEntity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicSets.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | /** 10 | * Defines a client-only entity for displaying audio/visual effects. 11 | */ 12 | struct AVEntity { 13 | enum class AVEntityBehavior { 14 | /** Move towards targetEntity. End early if it's reached. */ 15 | MoveToEntity, 16 | /** Move towards targetPosition. End early if it's reached. */ 17 | MoveToPosition, 18 | /** Move towards targetEntity for durationS seconds. */ 19 | FollowEntity 20 | }; 21 | 22 | struct Phase { 23 | /** The graphic set to use. */ 24 | EntityGraphicSet graphicSet{}; 25 | 26 | // TODO: Sounds 27 | 28 | /** The behavior that the entity should exhibit. */ 29 | AVEntityBehavior behavior{}; 30 | 31 | /** How fast the entity should move. */ 32 | float movementSpeed{}; 33 | 34 | /** How long this phase should run before timing out. */ 35 | float durationS{}; 36 | }; 37 | 38 | /** The phases that this entity will go through before being destroyed. */ 39 | std::vector phases{}; 40 | }; 41 | 42 | } // namespace AM 43 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/CastableData/CastFailureType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * All of the ways in which a Castable cast may fail. 10 | */ 11 | enum class CastFailureType : Uint8 { 12 | None, 13 | /** A client ID was provided, but the specified client does not exist. */ 14 | InvalidClient, 15 | /** The given castable ID doesn't exist. */ 16 | InvalidCastable, 17 | /** The caster entity is already casting something. */ 18 | AlreadyCasting, 19 | /** The requested cast is on cooldown, or the GCD is active. */ 20 | OnCooldown, 21 | /** The target entity or position is out of range of the caster. */ 22 | OutOfRange, 23 | /** The target item does not exist. */ 24 | InvalidItem, 25 | /** The target item or entity doesn't support the requested interaction 26 | type. */ 27 | InteractionNotSupported, 28 | /** The caster entity doesn't exist. */ 29 | InvalidCasterEntity, 30 | /** The target entity doesn't exist. */ 31 | InvalidTargetEntity, 32 | /** The target position is outside of the tile map. */ 33 | InvalidTargetPosition, 34 | /** The project's validateCast() call returned false. */ 35 | ProjectValidationFailed 36 | }; 37 | 38 | } // namespace AM 39 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/CastableData/CastableID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ItemInteractionType.h" 4 | #include "EntityInteractionType.h" 5 | #include "SpellType.h" 6 | #include "bitsery/ext/std_variant.h" 7 | #include 8 | 9 | namespace AM 10 | { 11 | 12 | /** 13 | * Identifies a castable. 14 | * 15 | * Castables fall into one of 3 types (item interaction, entity interaction, 16 | * spell), and are associated with an enum value. Only one castable can be 17 | * assigned to each type+value, so this ID is unique. 18 | */ 19 | using CastableID 20 | = std::variant; 21 | 22 | template 23 | void serialize(S& serializer, CastableID& castableID) 24 | { 25 | serializer.ext(castableID, 26 | bitsery::ext::StdVariant{[](S& serializer, auto& type) { 27 | serializer.value1b(type); 28 | }}); 29 | } 30 | 31 | } // namespace AM 32 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/CastableData/EngineCastableDef.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CastableID.h" 4 | #include "Castable.h" 5 | #include "GraphicDataBase.h" 6 | #include "SharedConfig.h" 7 | #include 8 | 9 | namespace AM 10 | { 11 | 12 | /** 13 | * Defines all of the engine-provided castables (item interactions, entity 14 | * interactions, and spells). 15 | */ 16 | class EngineCastableDef { 17 | public: 18 | static void defineCastables( 19 | const GraphicDataBase& graphicData, 20 | std::function addCastable) 21 | { 22 | addCastable(ItemInteractionType::Examine, 23 | Castable{.triggersGCD{false}}); 24 | 25 | addCastable( 26 | EntityInteractionType::Talk, 27 | Castable{ 28 | .range{SharedConfig::CAST_ENTITY_INTERACTION_STANDARD_RANGE}, 29 | .castTime{2}, 30 | .cooldownTime{2}, 31 | .triggersGCD{false}, 32 | .castingGraphicType{EntityGraphicType::Run}, 33 | //.castCompleteGraphicType{EntityGraphicType::Crouch}, 34 | .castCompleteVisualEffects{ 35 | {toGraphicID( 36 | graphicData.getAnimation("explosion").numericID), 37 | VisualEffect::LoopMode::Loop, 3}}}); 38 | } 39 | }; 40 | 41 | } // namespace AM 42 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/CastableData/VisualEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicID.h" 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * Defines a single visual effect. 10 | * 11 | * Typically, this will be attached to an entity to display a temporary graphic, 12 | * e.g. showing a heal graphic when an entity uses a health item. 13 | * 14 | * When the graphic is done playing, this effect is automatically destroyed. 15 | */ 16 | struct VisualEffect { 17 | /** The graphic to display. */ 18 | GraphicID graphicID{}; 19 | 20 | enum class LoopMode { 21 | PlayOnce, 22 | Loop 23 | }; 24 | 25 | /** If the graphic is an animation, this determines whether to play the 26 | animation once or to loop it. If the graphic is a sprite, this will 27 | be ignored (sprites are always treated as looping). */ 28 | LoopMode loopMode{}; 29 | 30 | /** If loopMode == Loop, this is how long to loop for. */ 31 | float loopTime{}; 32 | }; 33 | 34 | } // namespace AM 35 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/Collision.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BoundingBox.h" 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Represents an entity's collision bounds (a.k.a collision box, or just 9 | * collision). 10 | * 11 | * Entities use this component to define a consistent collision box. This 12 | * allows us to change their animation without worrying about re-calculating 13 | * their collision. 14 | * Tiles just use their graphic's model bounds to define their collision. 15 | */ 16 | struct Collision { 17 | /** Model-space bounding box. Defines the entity's 3D volume. 18 | Note: When an entity is constructed, we set this to match the default 19 | graphic's model bounds. This makes it easy for project devs to 20 | define the default entity collision. If the project dev wants 21 | different default collision for different entities, they can 22 | handle it in a project system. 23 | Note: When an entity's graphic set is updated, we automatically update 24 | this field to match the new set's IdleSouth. */ 25 | BoundingBox modelBounds{}; 26 | 27 | /** World-space bounding box. This is modelBounds, moved to the entity's 28 | position in the world. */ 29 | BoundingBox worldBounds{}; 30 | }; 31 | 32 | } // End namespace AM 33 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/EntityInitScript.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | /** 8 | * An entity's initialization script. Init scripts allow builders to customize 9 | * an entity by adding components and interactions to it. 10 | * 11 | * Init scripts are stored on the server in this component. When a client 12 | * wants to edit an entity, we send them that entity's script so they don't 13 | * have to start from scratch. 14 | * When a client sends an updated init script for an entity, we: 15 | * 1. Destruct the entity. 16 | * 2. Re-create it and add back its default components. 17 | * 3. Run the new init script on it. 18 | * 19 | * Init scripts aren't used by client entities. 20 | */ 21 | struct EntityInitScript { 22 | /** Used as a "we should never hit this" cap on the length of the script 23 | string. */ 24 | static constexpr std::size_t MAX_LENGTH{10000}; 25 | 26 | /** The initialization script. */ 27 | std::string script{}; 28 | }; 29 | 30 | template 31 | void serialize(S& serializer, EntityInitScript& initScript) 32 | { 33 | serializer.text1b(initScript.script, EntityInitScript::MAX_LENGTH); 34 | } 35 | 36 | } // namespace AM 37 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/GraphicState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GraphicSets.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * Holds graphic-related state that is shared between the client and server. 10 | * 11 | * For client-specific graphic state, see ClientGraphicState. 12 | * 13 | * The entity's collision box and mouse hit detection area (in build mode) are 14 | * derived from this state. 15 | */ 16 | struct GraphicState 17 | { 18 | EntityGraphicSetID graphicSetID{NULL_ENTITY_GRAPHIC_SET_ID}; 19 | }; 20 | 21 | template 22 | void serialize(S& serializer, GraphicState& graphicState) 23 | { 24 | serializer.value2b(graphicState.graphicSetID); 25 | } 26 | 27 | } // namespace AM 28 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/Input.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bitsery/ext/std_bitset.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * Represents an entity's current input states. 10 | * 11 | * In the server, when this component is updated, MovementSyncSystem auto-sends 12 | * movement state updates to all nearby clients. 13 | * If you want to sync an entity's movement state (e.g. Position) without 14 | * changing its inputs, you can just registry.patch() with no changes. 15 | */ 16 | struct Input { 17 | enum Type : Uint8 { XUp, XDown, YUp, YDown, Jump, Crouch, Count, None }; 18 | 19 | enum State : Uint8 { Released, Pressed }; 20 | 21 | /** Holds the current state of the inputs, indexed by Input::Type. */ 22 | using StateArr = std::bitset<6>; 23 | StateArr inputStates{}; 24 | }; 25 | 26 | template 27 | void serialize(S& serializer, Input& input) 28 | { 29 | // Bit pack the input bitset. 30 | serializer.enableBitPacking( 31 | [&input](typename S::BPEnabledType& sbp) { 32 | sbp.ext(input.inputStates, bitsery::ext::StdBitset{}); 33 | }); 34 | 35 | // Note: We shouldn't need to align after bit packing (when the context ends, 36 | // it'll auto-align), but measureSize() enables bit packing for 37 | // everything, so the context never ends and aligns itself. 38 | serializer.adapter().align(); 39 | } 40 | 41 | } // namespace AM 42 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/Interaction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EntityInteractionType.h" 4 | #include "SharedConfig.h" 5 | #include 6 | 7 | namespace AM 8 | { 9 | 10 | /** 11 | * Represents the interactions that an entity supports, i.e. the options that 12 | * show up when you right click them. 13 | * 14 | * Note: This component won't be present on an entity if it has no interactions. 15 | */ 16 | struct Interaction { 17 | /** The interactions that this entity supports. 18 | The first interaction in this list is the default interaction. */ 19 | std::vector supportedInteractions{}; 20 | 21 | /** 22 | * Adds the given interaction to supportedInteractions. 23 | * @return true if the interaction was added, else false (already present 24 | * or array was full). 25 | */ 26 | bool add(EntityInteractionType newInteraction); 27 | 28 | /** 29 | * Returns true if this component supports the given interaction. 30 | */ 31 | bool supports(EntityInteractionType desiredInteraction) const; 32 | 33 | /** 34 | * Returns this component's default interaction. 35 | */ 36 | EntityInteractionType getDefault() const; 37 | }; 38 | 39 | template 40 | void serialize(S& serializer, Interaction& interaction) 41 | { 42 | serializer.container1b(interaction.supportedInteractions, 43 | SharedConfig::MAX_ENTITY_INTERACTIONS); 44 | } 45 | 46 | } // End namespace AM 47 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/IsClientEntity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | /** 6 | * A tag struct used to tell if an entity belongs to a client or not. 7 | * 8 | * Terms: 9 | * "Client entities" are controlled by a client. 10 | * "Non-client entities" are controlled by the server (objects, npcs, etc). 11 | * "Player entity" is the client entity controlled by this client. 12 | * "Non-player-controlled entity (NPC)" is any non-player entity. This may be 13 | * a client entity or a non-client entity. 14 | */ 15 | struct IsClientEntity { 16 | // Note: No networked data. 17 | }; 18 | 19 | template 20 | void serialize(S&, IsClientEntity&) 21 | { 22 | // Note: No data to serialize. 23 | } 24 | 25 | } // namespace AM 26 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/Name.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Represents an entity's name. 9 | * 10 | * All entities have a name. 11 | */ 12 | struct Name { 13 | /** The max length of a name. */ 14 | static constexpr std::size_t MAX_LENGTH{50}; 15 | 16 | std::string value{""}; 17 | }; 18 | 19 | template 20 | void serialize(S& serializer, Name& name) 21 | { 22 | serializer.text1b(name.value, Name::MAX_LENGTH); 23 | } 24 | 25 | } // End namespace AM 26 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/Position.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Vector3.h" 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Represents a position in the world. 9 | * 10 | * All entities possess a Position component. 11 | * 12 | * Note: An entity's graphics will be aligned with its position (specifically, 13 | * the graphic's alignment anchor will be centered on the position). 14 | */ 15 | struct Position : Vector3 { 16 | Position operator=(const Vector3& vector) 17 | { 18 | x = vector.x; 19 | y = vector.y; 20 | z = vector.z; 21 | return *this; 22 | } 23 | }; 24 | 25 | template 26 | void serialize(S& serializer, Position& position) 27 | { 28 | serializer.value4b(position.x); 29 | serializer.value4b(position.y); 30 | serializer.value4b(position.z); 31 | } 32 | 33 | } // namespace AM 34 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/PreviousPosition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Position.h" 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Represents an entity's previous position. 9 | * Used for lerping during things like movement and rendering. 10 | */ 11 | struct PreviousPosition : Position { 12 | /** Used to tell if this position has been set or not. */ 13 | bool isInitialized{false}; 14 | 15 | PreviousPosition& operator=(const Position& other) 16 | { 17 | x = other.x; 18 | y = other.y; 19 | z = other.z; 20 | 21 | return *this; 22 | } 23 | }; 24 | 25 | } // namespace AM 26 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Components/SaveTimestamp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * Tracks the tick number when this entity was last saved. 10 | * 11 | * An example of usage is our CastCooldown component. It lazily updates its 12 | * timestamps, so if it gets saved on e.g. tick 500, it may have last been 13 | * updated on tick 450. When we load the component, we need to update it to 14 | * account for those 50 elapsed ticks. We can do that by using this timestamp. 15 | */ 16 | struct SaveTimestamp { 17 | /** The tick that this entity was last saved on. */ 18 | Uint32 lastSavedTick{}; 19 | }; 20 | 21 | template 22 | void serialize(S& serializer, SaveTimestamp& saveTimestamp) 23 | { 24 | serializer.value4b(saveTimestamp.lastSavedTick); 25 | } 26 | 27 | } // namespace AM 28 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Cylinder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Position.h" 4 | 5 | namespace AM 6 | { 7 | struct BoundingBox; 8 | 9 | /** 10 | * Represents a capped cylinder. 11 | */ 12 | struct Cylinder { 13 | /** Center point. */ 14 | Position center{}; 15 | 16 | /** Radius along the X/Y axes. */ 17 | float radius{0}; 18 | 19 | /** Half height along the Z axis. */ 20 | float halfHeight{0}; 21 | 22 | /** 23 | * Returns true if this cylinder intersects the given position. 24 | * 25 | * Note: Shared edges are considered to be intersecting. 26 | */ 27 | bool intersects(const Position& position) const; 28 | 29 | /** 30 | * Returns true if this cylinder intersects the given bounding box. 31 | * 32 | * Note: Shared edges are considered to be intersecting. 33 | */ 34 | bool intersects(const BoundingBox& boundingBox) const; 35 | 36 | /** 37 | * Prints this cylinder's current values. 38 | */ 39 | void print() const; 40 | }; 41 | 42 | } // End namespace AM 43 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/DialogueEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | /** Used as a "we should never hit this" cap on the text lengths. */ 10 | static constexpr std::size_t MAX_DIALOGUE_LINE_TEXT_LENGTH{500}; 11 | 12 | /** 13 | * Describes a piece of dialogue that was said. 14 | */ 15 | struct SayEvent 16 | { 17 | std::string text{}; 18 | }; 19 | 20 | /** 21 | * Describes anything that isn't verbal: actions, settings, thoughts, feelings. 22 | */ 23 | struct NarrateEvent 24 | { 25 | std::string text{}; 26 | }; 27 | 28 | /** 29 | * Describes how long to wait, in seconds, before handling the next event. 30 | */ 31 | struct WaitEvent 32 | { 33 | float waitTimeS{1}; 34 | }; 35 | 36 | /** A dialogue event. */ 37 | using DialogueEvent = std::variant; 38 | 39 | 40 | template 41 | void serialize(S& serializer, SayEvent& sayEvent) 42 | { 43 | serializer.text1b(sayEvent.text, MAX_DIALOGUE_LINE_TEXT_LENGTH); 44 | } 45 | 46 | template 47 | void serialize(S& serializer, NarrateEvent& narrateEvent) 48 | { 49 | serializer.text1b(narrateEvent.text, MAX_DIALOGUE_LINE_TEXT_LENGTH); 50 | } 51 | 52 | template 53 | void serialize(S& serializer, WaitEvent& waitEvent) 54 | { 55 | serializer.value4b(waitEvent.waitTimeS); 56 | } 57 | 58 | } // namespace AM 59 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/DiscreteImpl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | namespace DiscreteImpl 6 | { 7 | /** 8 | * A tag type to express that a DiscreteRange or DiscretePosition is using 9 | * tiles as its unit. 10 | */ 11 | struct TileTag { 12 | }; 13 | 14 | /** 15 | * A tag type to express that a DiscreteRange or DiscretePosition is using 16 | * chunks as its unit. 17 | */ 18 | struct ChunkTag { 19 | }; 20 | 21 | /** 22 | * A tag type to express that a DiscreteRange or DiscretePosition is using 23 | * spatial partitioning grid cells as its unit. 24 | */ 25 | struct CellTag { 26 | }; 27 | 28 | } // namespace DiscreteImpl 29 | 30 | } // End namespace AM 31 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/EngineEntityGraphicType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * The entity graphic types that the engine provides. 10 | * 11 | * Note: Don't use this enum directly, use EntityGraphicType (it combines 12 | * the engine's and the project's graphic types). 13 | */ 14 | enum class EngineEntityGraphicType : Uint8 { 15 | NotSet, 16 | /** Note: All graphic sets are expected to contain the South Idle graphic. */ 17 | Idle, 18 | Run, 19 | Crouch, 20 | Jump, 21 | PROJECT_START 22 | }; 23 | 24 | } // End namespace AM 25 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/EngineEntityInteractionType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * The types of entity interactions that the engine provides. 10 | * 11 | * Note: Don't use this enum directly, use EntityInteractionType (it combines 12 | * the engine's and the project's interactions). 13 | */ 14 | enum class EngineEntityInteractionType : Uint8 { 15 | NotSet, 16 | Talk, 17 | 18 | // We reserve values 0 - 49. The project can start at 50. 19 | PROJECT_START = 50 20 | }; 21 | 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/EngineItemInteractionType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * The types of item interactions that the engine provides. 10 | * 11 | * Note: Don't use this enum directly, use ItemInteractionType (it combines the 12 | * engine's and the project's interactions). 13 | */ 14 | enum class EngineItemInteractionType : Uint8 { 15 | NotSet, 16 | 17 | // Note: All items support Examine, Destroy (handled by 18 | // InventoryDeleteItem), and UseOn (handled by CombineItems and 19 | // UseItemOnEntityRequest). 20 | UseOn, 21 | Destroy, 22 | Examine, 23 | 24 | // We reserve values 0 - 49. The project can start at 50. 25 | PROJECT_START = 50 26 | }; 27 | 28 | } // End namespace AM 29 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/EnttObserver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "entt/fwd.hpp" 4 | #include "entt/entity/registry.hpp" 5 | 6 | namespace AM 7 | { 8 | /** 9 | * A reactive storage that can observe changes to a single component type. 10 | * 11 | * To bind: 12 | * observer.bind(registry); 13 | * observer.on_construct(); // on_update, on_destroy 14 | * 15 | * To view: 16 | * for (entt::entity entity : observer) { 17 | * // (process things here) 18 | * } 19 | * observer.clear(); 20 | */ 21 | using EnttObserver = entt::reactive_mixin>; 22 | 23 | } // End namespace AM 24 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/GraphicData/AnimationID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** An animation's numeric ID. */ 9 | using AnimationID = Uint16; 10 | 11 | /** 12 | * The ID of the "null animation", or the ID used to indicate that an animation 13 | * is not present. 14 | * 15 | * Note: Since the null ID is 0, you can do null checks like "if (animationID)". 16 | */ 17 | static constexpr AnimationID NULL_ANIMATION_ID{0}; 18 | 19 | } // End namespace AM 20 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/GraphicData/GraphicSetIDs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** 9 | * A graphic set's numeric ID. 10 | * 11 | * These IDs aren't super useful since we cast to Uint16 all the time for 12 | * generic code, but they at least give a solid indication that each graphic 13 | * set type has its own ID space. 14 | * 15 | * If we ever care to, we can replace everywhere we cast to Uint16 with a 16 | * variant that contains these types. 17 | */ 18 | using TerrainGraphicSetID = Uint16; 19 | using FloorGraphicSetID = Uint16; 20 | using WallGraphicSetID = Uint16; 21 | using ObjectGraphicSetID = Uint16; 22 | using EntityGraphicSetID = Uint16; 23 | 24 | /** 25 | * The ID of the "null graphic set", or the ID used to indicate that a graphic 26 | * set is not present. 27 | * 28 | * Note: Since the null ID is 0, you can do null checks like "if (graphicSetID)". 29 | */ 30 | static constexpr TerrainGraphicSetID NULL_TERRAIN_GRAPHIC_SET_ID{0}; 31 | static constexpr FloorGraphicSetID NULL_FLOOR_GRAPHIC_SET_ID{0}; 32 | static constexpr WallGraphicSetID NULL_WALL_GRAPHIC_SET_ID{0}; 33 | static constexpr ObjectGraphicSetID NULL_OBJECT_GRAPHIC_SET_ID{0}; 34 | static constexpr EntityGraphicSetID NULL_ENTITY_GRAPHIC_SET_ID{0}; 35 | 36 | } // End namespace AM 37 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/GraphicData/SpriteID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** A sprite's numeric ID. */ 9 | using SpriteID = Uint32; 10 | 11 | /** 12 | * The ID of the "null sprite", or the ID used to indicate that a sprite is 13 | * not present. 14 | * 15 | * One example of usage is in graphic sets: if an Object graphic set doesn't 16 | * implement some rotations, those slots are set to the null sprite. 17 | * 18 | * Note: Since the null ID is 0, you can do null checks like "if (spriteID)". 19 | */ 20 | static constexpr SpriteID NULL_SPRITE_ID{0}; 21 | 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/IconData/Icon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IconID.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | /** 9 | * Holds the data for a single icon from ResourceData.json. 10 | */ 11 | struct Icon { 12 | /** Unique display name, shown in the UI. */ 13 | std::string displayName{"Null"}; 14 | 15 | /** The icon's unique string ID. Derived from displayName by replacing 16 | spaces with underscores and making everything lowercase. 17 | This ID will be consistent, and can be used for persistent state. */ 18 | std::string stringID{"null"}; 19 | 20 | /** This icon's unique numeric identifier. 21 | This value can be used safely at runtime, but shouldn't be used for 22 | persistent state since it may change when ResourceData.json is 23 | modified. */ 24 | IconID numericID{NULL_ICON_ID}; 25 | }; 26 | 27 | } // namespace AM 28 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/IconData/IconID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** An icon's numeric ID. */ 9 | using IconID = Uint16; 10 | 11 | /** 12 | * The ID of the "null icon", or the ID used to indicate that an icon is 13 | * not present. 14 | * 15 | * Note: Since the null ID is 0, you can do null checks like "if (iconID)". 16 | */ 17 | static constexpr IconID NULL_ICON_ID{0}; 18 | 19 | } // End namespace AM 20 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/ItemData/ItemCombination.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ItemID.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | 9 | /** 10 | * Defines a combination between two items. 11 | * 12 | * Occurs when a user "Use"s an item, then selects a target item. 13 | */ 14 | struct ItemCombination { 15 | /** The max length of the description text. */ 16 | static constexpr std::size_t MAX_DESCRIPTION_LENGTH{500}; 17 | 18 | /** The item to combine with. */ 19 | ItemID otherItemID{NULL_ITEM_ID}; 20 | 21 | /** The resulting item. */ 22 | ItemID resultItemID{NULL_ITEM_ID}; 23 | 24 | /** The descriptive text to send to the client when this combination 25 | succeeds. */ 26 | std::string description{}; 27 | }; 28 | 29 | template 30 | void serialize(S& serializer, ItemCombination& itemCombination) 31 | { 32 | serializer.value2b(itemCombination.otherItemID); 33 | serializer.value2b(itemCombination.resultItemID); 34 | serializer.text1b(itemCombination.description, 35 | ItemCombination::MAX_DESCRIPTION_LENGTH); 36 | } 37 | 38 | } // End namespace AM 39 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/ItemData/ItemID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | 8 | /** An item's numeric ID. 9 | Note: Once created, items can't be deleted. You can, however, repurpose an 10 | ID by updating that item's definition. */ 11 | using ItemID = Uint16; 12 | 13 | /** 14 | * The ID of the "null item", or the ID used to indicate that an item is 15 | * not present. 16 | * 17 | * Note: Since the null ID is 0, you can do null checks like "if (itemID)". 18 | */ 19 | static constexpr ItemID NULL_ITEM_ID{0}; 20 | 21 | /** An item's version. 22 | Each time an item's definition is changed, its version gets incremented. 23 | Used by clients to tell if they have the latest item definition, or if they 24 | need to request it.*/ 25 | using ItemVersion = Uint16; 26 | 27 | } // End namespace AM 28 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/ItemData/ItemInitScript.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | /** 8 | * An item's initialization script. Init scripts allow builders to customize 9 | * an item by adding properties and interactions to it. 10 | * 11 | * Init scripts are stored on the server. When a client wants to edit an item, 12 | * we send them that item's script so they don't have to start from scratch. 13 | * When a client sends an updated init script for an item, we: 14 | * 1. Reset the item to a default state. 15 | * 2. Run the new init script on it. 16 | */ 17 | struct ItemInitScript { 18 | /** Used as a "we should never hit this" cap on the length of the script 19 | string. */ 20 | static constexpr std::size_t MAX_LENGTH{10000}; 21 | 22 | /** The initialization script. */ 23 | std::string script{}; 24 | }; 25 | 26 | template 27 | void serialize(S& serializer, ItemInitScript& initScript) 28 | { 29 | serializer.text1b(initScript.script, ItemInitScript::MAX_LENGTH); 30 | } 31 | 32 | } // namespace AM 33 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/ItemData/ItemProperty.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ProjectItemPropertyTypes.h" 4 | #include "boost/mp11/list.hpp" 5 | #include "boost/mp11/algorithm.hpp" 6 | #include 7 | 8 | namespace AM 9 | { 10 | 11 | /** 12 | * A variant that holds the proterties that may be attached to an item. 13 | * 14 | * Note: Since the engine doesn't have any properties to provide, we can just 15 | * alias the project list. This lets us avoid migration issues without 16 | * having to persist the property lists separately (like we do for 17 | * entity components). 18 | */ 19 | using ItemProperty 20 | = boost::mp11::mp_rename; 21 | 22 | // Since all members of a variant are the size of the largest member, we enforce 23 | // a size constraint. 24 | static_assert(sizeof(ItemProperty) <= 64, 25 | "An item property struct is too large. Please reduce its size to " 26 | "<= 64B or allocate its fields dynamically."); 27 | 28 | } // End namespace AM 29 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/Ray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Vector3.h" 4 | #include 5 | #include 6 | 7 | namespace AM 8 | { 9 | /** 10 | * Represents a world-space ray. 11 | * 12 | * A ray is a single point in space with a direction. It extends infinitely far 13 | * in that single direction (as opposed to a line, which extends in both 14 | * directions). 15 | */ 16 | struct Ray { 17 | /** Origin point. */ 18 | Vector3 origin{}; 19 | 20 | /** Direction vector. */ 21 | Vector3 direction{}; 22 | 23 | /** 24 | * Returns the point along this ray at the given t. 25 | */ 26 | Vector3 getPointAtT(float t); 27 | 28 | /** 29 | * Prints this ray's current values. 30 | */ 31 | void print() const; 32 | }; 33 | 34 | } // namespace AM 35 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/ReplicatedComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "EngineReplicatedComponentTypes.h" 4 | #include "ProjectReplicatedComponentTypes.h" 5 | #include "boost/mp11/list.hpp" 6 | #include "boost/mp11/algorithm.hpp" 7 | #include 8 | 9 | namespace AM 10 | { 11 | 12 | /** 13 | * See comment in EngineReplicatedComponentTypes.h 14 | */ 15 | using ReplicatedComponentTypes 16 | = boost::mp11::mp_append; 18 | // Note: This limit is only to prevent data sizes from getting larger. If we 19 | // let there be more than 256 components, every component's index would 20 | // start taking 2B instead of 1B. 21 | static_assert(boost::mp11::mp_size::value 22 | <= (SDL_MAX_UINT8 + 1), 23 | "Too many types in ReplicatedComponentTypes. Max is 256."); 24 | 25 | /** 26 | * A variant that holds a client-relevant component. 27 | * 28 | * Used by the server to send components to the client (so it can replicate 29 | * them). 30 | */ 31 | using ReplicatedComponent 32 | = boost::mp11::mp_rename; 33 | 34 | } // End namespace AM 35 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/ResourceData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "nlohmann/json_fwd.hpp" 5 | 6 | namespace AM 7 | { 8 | 9 | /** 10 | * Parses ResourceData.json into an in-memory object so we can pass it to 11 | * GraphicData, IconData, etc. 12 | * 13 | * Note: This class expects a ResourceData.json file to be present in the same 14 | * directory as the application executable. 15 | */ 16 | class ResourceData 17 | { 18 | public: 19 | /** 20 | * Parses ResourceData.json. Errors if it fails to parse. 21 | */ 22 | ResourceData(); 23 | 24 | ~ResourceData(); 25 | 26 | /** 27 | * Returns the parsed json object. 28 | */ 29 | nlohmann::json& get(); 30 | 31 | private: 32 | // Note: We use a pointer so we can forward declare. 33 | std::unique_ptr resourceDataJson; 34 | }; 35 | 36 | } // End namespace AM 37 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/TileMap/Chunk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Tile.h" 4 | #include "SharedConfig.h" 5 | #include 6 | #include 7 | 8 | namespace AM 9 | { 10 | struct Sprite; 11 | 12 | /** 13 | * A 32x32-unit tile in the tile map. 14 | * 15 | * A tile consists of layers of sprites, which can be floors, walls, etc. 16 | * 17 | * Tiles contain no logic. If something on a tile requires logic, e.g. a tree 18 | * growing over time, it must have a system act upon it. 19 | */ 20 | class Chunk 21 | { 22 | public: 23 | /** The number of tiles in the tiles array that are non-empty. 24 | Used to tell when this chunk is empty and can be deleted. */ 25 | Uint16 tileLayerCount{0}; 26 | 27 | /** The tiles that make up this chunk, stored in morton order. */ 28 | std::array tiles{}; 29 | 30 | /** 31 | * Returns the tile at the given tile coordinate offset (with respect to 32 | * this chunk's origin). 33 | */ 34 | Tile& getTile(Uint16 tileOffsetX, Uint16 tileOffsetY); 35 | const Tile& getTile(Uint16 tileOffsetX, Uint16 tileOffsetY) const; 36 | 37 | private: 38 | /** 39 | * Returns a morton code for the given x and y. 40 | * We use morton codes to lay out our tiles in a more cache-friendly way 41 | * since we're likely to be accessing neighbors at the same time. 42 | */ 43 | Uint32 mortonEncode(Uint16 x, Uint16 y) const; 44 | }; 45 | 46 | } // End namespace AM 47 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/TileMap/ChunkExtent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DiscreteExtent.h" 4 | #include 5 | 6 | namespace AM 7 | { 8 | struct TileExtent; 9 | 10 | /** 11 | * A strong type alias, describing an extent of map chunks. 12 | */ 13 | struct ChunkExtent : public DiscreteExtent { 14 | ChunkExtent(); 15 | 16 | ChunkExtent(int inX, int inY, int inZ, int inXLength, int inYLength, 17 | int inZLength); 18 | 19 | ChunkExtent(const DiscreteExtent& chunkExtent); 20 | 21 | explicit ChunkExtent(const TileExtent& tileExtent); 22 | 23 | /** 24 | * Prints this extent's current values. 25 | */ 26 | void print() const; 27 | 28 | /** 29 | * Builds a ChunkExtent from the given tile map lengths, centering it 30 | * around (0, 0) in the x and y directions, and starting at 0 in the z 31 | * direction. 32 | */ 33 | static ChunkExtent fromMapLengths(Uint16 mapXLengthChunks, 34 | Uint16 mapYLengthChunks, 35 | Uint16 mapZLengthChunks); 36 | }; 37 | 38 | } // End namespace AM 39 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/TileMap/Floor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BoundingBox.h" 4 | 5 | namespace AM 6 | { 7 | struct TilePosition; 8 | 9 | /** 10 | * Definitions and helper functions for working with Floor tile layers. 11 | */ 12 | struct Floor { 13 | /** 14 | * Returns a bounding volume for a floor, translated to world space and 15 | * offset to the given tile coords. 16 | */ 17 | static BoundingBox calcWorldBounds(const TilePosition& tilePosition); 18 | }; 19 | 20 | } // End namespace AM 21 | -------------------------------------------------------------------------------- /Source/SharedLib/Simulation/Public/TileMap/Wall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | struct Wall { 8 | /** 9 | * The types of wall graphics that we use for our modular wall system. 10 | */ 11 | enum Type : Uint8 { 12 | /** A West wall. */ 13 | West, 14 | /** A North wall. */ 15 | North, 16 | /** A column used to fill SouthEast-pointing corners. Gets placed on the 17 | tile southeast of the north and west walls that form the corner. */ 18 | NorthWestGapFill, 19 | /** A 3/4 North wall used to fill NorthWest-pointing corners. Gets 20 | placed on the same tile as a west wall to form the corner. */ 21 | NorthEastGapFill, 22 | /** The number of different wall types that we have. */ 23 | Count, 24 | /** Used to tell if a tile layer doesn't contain a wall. */ 25 | None 26 | }; 27 | }; 28 | 29 | } // End namespace AM 30 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Private/Paths.cpp: -------------------------------------------------------------------------------- 1 | #include "Paths.h" 2 | #include 3 | 4 | namespace AM 5 | { 6 | // Note: It would be nice if we could trivially free this after making it a 7 | // string, but it isn't a big deal. 8 | const char* BASE_PATH_INTERNAL = SDL_GetBasePath(); 9 | 10 | const std::string Paths::BASE_PATH = std::string{BASE_PATH_INTERNAL}; 11 | 12 | const std::string Paths::FONT_DIR 13 | = std::string{Paths::BASE_PATH} + "Assets/Fonts/"; 14 | 15 | const std::string Paths::TEXTURE_DIR 16 | = std::string{Paths::BASE_PATH} + "Assets/Textures/"; 17 | 18 | } // End namespace AM 19 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Private/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include "SDL.h" 3 | 4 | namespace AM 5 | { 6 | Timer::Timer() 7 | : period{1.0 / SDL_GetPerformanceFrequency()} 8 | , savedTimestamp{SDL_GetPerformanceCounter()} 9 | { 10 | } 11 | 12 | double Timer::getTime() 13 | { 14 | Uint64 currentTicks{SDL_GetPerformanceCounter()}; 15 | Uint64 deltaTicks{currentTicks - savedTimestamp}; 16 | 17 | return deltaTicks * period; 18 | } 19 | 20 | void Timer::reset() 21 | { 22 | savedTimestamp = SDL_GetPerformanceCounter(); 23 | } 24 | 25 | double Timer::getTimeAndReset() 26 | { 27 | Uint64 currentTicks{SDL_GetPerformanceCounter()}; 28 | Uint64 deltaTicks{currentTicks - savedTimestamp}; 29 | 30 | savedTimestamp = currentTicks; 31 | 32 | return deltaTicks * period; 33 | } 34 | 35 | double Timer::getGlobalTime() 36 | { 37 | static Timer timer{}; 38 | return timer.getTime(); 39 | } 40 | 41 | } // namespace AM 42 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Private/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // STL 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // Libs 11 | #include 12 | 13 | // Ours 14 | #include "Log.h" 15 | #include "NetworkDefs.h" 16 | #include "SharedConfig.h" 17 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/AMAssert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Log.h" 4 | 5 | /** 6 | * Assert macro. Use this in place of assert(). 7 | */ 8 | #ifdef NDEBUG 9 | #define AM_ASSERT(condition, ...) \ 10 | do { \ 11 | } while (false) 12 | #else 13 | #define AM_ASSERT(condition, ...) \ 14 | do { \ 15 | if (!(condition)) { \ 16 | LOG_ERROR(__VA_ARGS__); \ 17 | } \ 18 | } while (false) 19 | #endif 20 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/BinaryBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace AM 8 | { 9 | /** Dynamically allocated, portable buffers for bytes. */ 10 | using BinaryBuffer = std::vector; 11 | using BinaryBufferPtr = std::unique_ptr; 12 | using BinaryBufferSharedPtr = std::shared_ptr; 13 | 14 | } // End namespace AM 15 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/ConstexprTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | 6 | /** 7 | * Common helper functions for constexpr use. 8 | * 9 | * Note: This shouldn't be necessary since a lot of std algorithms are 10 | * constexpr in gcc, but they aren't constexpr in msvc yet. 11 | */ 12 | class ConstexprTools 13 | { 14 | public: 15 | /** 16 | * Computes the smallest integer value not less than the given value. 17 | * 18 | * Reference: https://stackoverflow.com/a/66146159/4258629 19 | */ 20 | static constexpr int ceilInt(float value) 21 | { 22 | const int truncated{static_cast(value)}; 23 | return (value > truncated) ? (truncated + 1) : truncated; 24 | } 25 | 26 | /** 27 | * Computes the largest integer value not greater than the given value. 28 | * 29 | * Reference: https://stackoverflow.com/a/66146159/4258629 30 | */ 31 | static constexpr int floorInt(float value) 32 | { 33 | const int truncated{static_cast(value)}; 34 | return (value < truncated) ? (truncated - 1) : truncated; 35 | } 36 | }; 37 | 38 | } // End namespace AM 39 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/OSEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Simple interface to facilitate event handling and propagation. 9 | * 10 | * Specifically meant for OS events, provided by SDL2. Intra-app events have 11 | * other data flow paths. 12 | */ 13 | class OSEventHandler 14 | { 15 | public: 16 | virtual ~OSEventHandler(){}; 17 | 18 | /** 19 | * Handles the given event. 20 | * 21 | * Since synchronous feedback is required, it's advised that an implementor 22 | * limit work done in this function. If significant time must be spent, 23 | * consider only doing as much work as is necessary to determine if the 24 | * event will be handled, and defer processing until later. 25 | * 26 | * @return true if the event has been handled and should stop propagating, 27 | * else false. 28 | */ 29 | virtual bool handleOSEvent(SDL_Event& event) = 0; 30 | }; 31 | 32 | } // End namespace AM 33 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/Paths.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Used for accessing files in expected directories. 9 | * 10 | * The Client and ResourceImporter expect a particular asset directory 11 | * structure, starting at the binary's location: 12 | * . 13 | * └── Assets 14 | *    ├── Fonts 15 | *    └── Textures 16 | */ 17 | class Paths 18 | { 19 | public: 20 | /** The path that the application was ran from. 21 | Note: Use this instead of SDL_GetBasePath() to easily avoid leaking 22 | memory. */ 23 | static const std::string BASE_PATH; 24 | 25 | /** The expected path to the root of the Fonts directory. */ 26 | static const std::string FONT_DIR; 27 | 28 | /** The expected path to the root of the Textures directory. */ 29 | static const std::string TEXTURE_DIR; 30 | }; 31 | 32 | } // End namespace AM 33 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/StringTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /** 7 | * Static functions for working with strings. 8 | */ 9 | namespace AM 10 | { 11 | class StringTools 12 | { 13 | public: 14 | /** 15 | * Derives a string ID from a display name by making it all lowercase and 16 | * replacing spaces with underscores. 17 | * 18 | * Note: This uses an out param instead of returning the string because it's 19 | * used in performance-sensitive situations where we need to re-use 20 | * a pre-allocated string. 21 | */ 22 | static void deriveStringID(std::string_view displayName, std::string& dest); 23 | 24 | /** 25 | * Returns the name of the file at the given path, including extension. 26 | */ 27 | static std::string_view getFileName(std::string_view filePath); 28 | 29 | /** 30 | * Returns the name of the file at the given path, with no extension. 31 | */ 32 | static std::string_view getFileNameNoExtension(std::string_view filePath); 33 | 34 | /** 35 | * Returns true if pathA starts with the characters in pathB, ignoring 36 | * differences in slash type used ('/' vs '\'). 37 | */ 38 | static bool pathStartsWith(std::string_view pathA, std::string_view pathB); 39 | }; 40 | 41 | } // End namespace AM 42 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace AM 6 | { 7 | /** 8 | * Uses the SDL high resolution timer to produce time deltas. 9 | */ 10 | class Timer 11 | { 12 | public: 13 | Timer(); 14 | 15 | /** 16 | * Returns the amount of time that this timer has been running. 17 | * 18 | * @return The amount of time in seconds since the saved time was last 19 | * updated. 20 | */ 21 | double getTime(); 22 | 23 | /** 24 | * Resets this timer to 0. 25 | */ 26 | void reset(); 27 | 28 | /** 29 | * Returns the amount of time that this timer has been running, then 30 | * resets it to 0. 31 | */ 32 | double getTimeAndReset(); 33 | 34 | /** 35 | * Returns a monotonic amount of time since this function was first called 36 | * (usually during app startup). 37 | */ 38 | static double getGlobalTime(); 39 | 40 | private: 41 | /** How fast the processor is running. SDL sets this once on init and 42 | never changes it. */ 43 | double period; 44 | 45 | /** The saved time in integer ticks from SDL_GetPerformanceCounter(). */ 46 | Uint64 savedTimestamp; 47 | }; 48 | 49 | } // namespace AM 50 | -------------------------------------------------------------------------------- /Source/SharedLib/Utility/Public/VariantTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AM 4 | { 5 | 6 | /** 7 | * Common helper functions for std::variant use. 8 | */ 9 | namespace VariantTools 10 | { 11 | 12 | template 13 | struct Overload : Ts... { 14 | using Ts::operator()...; 15 | }; 16 | 17 | template 18 | Overload(Ts...) -> Overload; 19 | 20 | } 21 | 22 | } // End namespace AM 23 | -------------------------------------------------------------------------------- /Source/Tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Configure tests. 2 | add_subdirectory(TestSandboxes) 3 | 4 | #add_subdirectory(UnitTests) 5 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Build test apps. 2 | #add_subdirectory(Graphics) 3 | 4 | add_subdirectory(Network) 5 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Graphics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | message(STATUS "Configuring Graphics Test Apps") 4 | 5 | # Latency test client 6 | add_executable(FrameTimeTest 7 | Private/FrameTimeTestMain.cpp 8 | ) 9 | 10 | target_include_directories(FrameTimeTest 11 | PRIVATE 12 | ${SDL2_INCLUDE_DIRS} 13 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 14 | ) 15 | 16 | target_link_libraries(FrameTimeTest 17 | PRIVATE 18 | ${SDL2_LIBRARIES} 19 | Shared 20 | ) 21 | 22 | target_compile_features(FrameTimeTest PRIVATE cxx_std_23) 23 | set_target_properties(FrameTimeTest PROPERTIES CXX_EXTENSIONS OFF) 24 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Graphics/Private/FrameTimeTestMain.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Net5F/AmalgamEngine/5462508d236832a33885f31ee9fdfb6770fd3381/Source/Tests/TestSandboxes/Graphics/Private/FrameTimeTestMain.cpp -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Network/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Build test apps. 2 | #add_subdirectory(ClockTest) 3 | 4 | #add_subdirectory(DriftTest) 5 | 6 | #add_subdirectory(LatencyTest) 7 | 8 | add_subdirectory(LoadTest) 9 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Network/ClockTest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | message(STATUS "Configuring Clock Test") 4 | 5 | # Clock test client 6 | add_executable(ClockTestClient 7 | Private/ClockTestClientMain.cpp 8 | ) 9 | target_include_directories(ClockTestClient 10 | PRIVATE 11 | ${SDL2_INCLUDE_DIRS} 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 13 | ) 14 | target_link_libraries(ClockTestClient 15 | PRIVATE 16 | ${SDL2_LIBRARIES} 17 | SDL2_net-static 18 | SharedLib 19 | ) 20 | target_compile_features(ClockTestClient PRIVATE cxx_std_23) 21 | set_target_properties(ClockTestClient PROPERTIES CXX_EXTENSIONS OFF) 22 | 23 | # Clock test server 24 | add_executable(ClockTestServer 25 | Private/ClockTestServerMain.cpp 26 | ) 27 | target_include_directories(ClockTestServer 28 | PRIVATE 29 | ${SDL2_INCLUDE_DIRS} 30 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 31 | ) 32 | target_link_libraries(ClockTestServer 33 | PRIVATE 34 | ${SDL2_LIBRARIES} 35 | SDL2_net-static 36 | SharedLib 37 | ) 38 | target_compile_features(ClockTestServer PRIVATE cxx_std_23) 39 | set_target_properties(ClockTestServer PROPERTIES CXX_EXTENSIONS OFF) 40 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Network/DriftTest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | message(STATUS "Configuring Drift Test") 4 | 5 | # Drift test client 6 | add_executable(DriftTestClient 7 | Private/DriftTestClientMain.cpp 8 | ) 9 | target_include_directories(DriftTestClient 10 | PRIVATE 11 | ${SDL2_INCLUDE_DIRS} 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 13 | ) 14 | target_link_libraries(DriftTestClient 15 | PRIVATE 16 | ${SDL2_LIBRARIES} 17 | SDL2_net-static 18 | SharedLib 19 | ) 20 | target_compile_features(DriftTestClient PRIVATE cxx_std_23) 21 | set_target_properties(DriftTestClient PROPERTIES CXX_EXTENSIONS OFF) 22 | 23 | # Drift test server 24 | add_executable(DriftTestServer 25 | Private/DriftTestServerMain.cpp 26 | ) 27 | target_include_directories(DriftTestServer 28 | PRIVATE 29 | ${SDL2_INCLUDE_DIRS} 30 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 31 | ) 32 | target_link_libraries(DriftTestServer 33 | PRIVATE 34 | ${SDL2_LIBRARIES} 35 | SDL2_net-static 36 | SharedLib 37 | ) 38 | target_compile_features(DriftTestServer PRIVATE cxx_std_23) 39 | set_target_properties(DriftTestServer PROPERTIES CXX_EXTENSIONS OFF) 40 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Network/LatencyTest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | message(STATUS "Configuring Latency Test") 4 | 5 | # Latency test client 6 | add_executable(LatencyTestClient 7 | Private/LatencyTestClientMain.cpp 8 | ) 9 | target_include_directories(LatencyTestClient 10 | PRIVATE 11 | ${SDL2_INCLUDE_DIRS} 12 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 13 | ) 14 | target_link_libraries(LatencyTestClient 15 | PRIVATE 16 | ${SDL2_LIBRARIES} 17 | SDL2_net-static 18 | SharedLib 19 | ) 20 | target_compile_features(LatencyTestClient PRIVATE cxx_std_23) 21 | set_target_properties(LatencyTestClient PROPERTIES CXX_EXTENSIONS OFF) 22 | 23 | # Latency test server 24 | add_executable(LatencyTestServer 25 | Private/LatencyTestServerMain.cpp 26 | ) 27 | target_include_directories(LatencyTestServer 28 | PRIVATE 29 | ${SDL2_INCLUDE_DIRS} 30 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 31 | ) 32 | target_link_libraries(LatencyTestServer 33 | PRIVATE 34 | ${SDL2_LIBRARIES} 35 | SDL2_net-static 36 | SharedLib 37 | ) 38 | target_compile_features(LatencyTestServer PRIVATE cxx_std_23) 39 | set_target_properties(LatencyTestServer PROPERTIES CXX_EXTENSIONS OFF) 40 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Network/LoadTest/Private/SimulatedClient.cpp: -------------------------------------------------------------------------------- 1 | #include "SimulatedClient.h" 2 | #include "SharedConfig.h" 3 | #include 4 | 5 | namespace AM 6 | { 7 | namespace LTC 8 | { 9 | SimulatedClient::SimulatedClient(unsigned int inInputsPerSecond) 10 | : networkCaller(std::bind_front(&NetworkSimulation::tick, &networkSim), 11 | SharedConfig::CLIENT_NETWORK_TICK_TIMESTEP_S, "Network", true) 12 | , worldSim(networkSim, inInputsPerSecond) 13 | , simCaller(std::bind_front(&WorldSimulation::tick, &worldSim), 14 | SharedConfig::SIM_TICK_TIMESTEP_S, "Sim", false) 15 | , isConnected(false) 16 | { 17 | } 18 | 19 | void SimulatedClient::connect() 20 | { 21 | // Connect to the server. 22 | worldSim.connect(); 23 | 24 | // Start the tick timer at the current time. 25 | simCaller.initTimer(); 26 | networkCaller.initTimer(); 27 | 28 | isConnected = true; 29 | } 30 | 31 | void SimulatedClient::receiveAndProcess() 32 | { 33 | // Note: This is safe to call, even if connect() is running on another 34 | // thread (it has an internal check). 35 | networkSim.receiveAndProcess(); 36 | } 37 | 38 | void SimulatedClient::tick() 39 | { 40 | // Process the network. 41 | networkCaller.update(); 42 | 43 | // If we're connected, process the world sim. 44 | if (isConnected) { 45 | simCaller.update(); 46 | } 47 | } 48 | 49 | } // End namespace LTC 50 | } // End namespace AM 51 | -------------------------------------------------------------------------------- /Source/Tests/TestSandboxes/Network/LoadTest/Public/SimulatedClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NetworkSimulation.h" 4 | #include "WorldSimulation.h" 5 | #include "PeriodicCaller.h" 6 | #include 7 | 8 | namespace AM 9 | { 10 | namespace LTC 11 | { 12 | /** 13 | * Represents a single simulated client. 14 | * Maintains only as much state as is necessary to keep the connection going 15 | * and send inputs. 16 | */ 17 | class SimulatedClient 18 | { 19 | public: 20 | SimulatedClient(unsigned int inInputsPerSecond); 21 | 22 | /** 23 | * Calls worldSim.connect(). 24 | */ 25 | void connect(); 26 | 27 | /** 28 | * Calls networkSim.receiveAndProcess(). 29 | */ 30 | void receiveAndProcess(); 31 | 32 | /** 33 | * Calls the sim and network ticks. 34 | */ 35 | void tick(); 36 | 37 | private: 38 | NetworkSimulation networkSim; 39 | PeriodicCaller networkCaller; 40 | 41 | WorldSimulation worldSim; 42 | PeriodicCaller simCaller; 43 | 44 | /** If true, this client is connected to the server and we've processed the 45 | ConnectionResponse. */ 46 | std::atomic isConnected; 47 | }; 48 | 49 | } // End namespace LTC 50 | } // End namespace AM 51 | -------------------------------------------------------------------------------- /Source/Tests/UnitTests/Private/TestMain.cpp: -------------------------------------------------------------------------------- 1 | #include "catch2/catch_all.hpp" 2 | 3 | int main(int argc, char* argv[]) 4 | { 5 | /* Run Tests */ 6 | int result = Catch::Session().run(argc, argv); 7 | 8 | return result; 9 | } 10 | -------------------------------------------------------------------------------- /Source/Tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Configure tools. 2 | # Note: This doesn't have a real implementation yet, just some example code. 3 | # It's expected to not compile without changes. 4 | #add_subdirectory(EngineDatabaseMigrator) 5 | -------------------------------------------------------------------------------- /Source/Tools/EngineDatabaseMigrator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | message(STATUS "Configuring EngineDatabaseMigrator") 4 | 5 | add_executable(EngineDatabaseMigrator 6 | Private/EngineDatabaseMigratorMain.cpp 7 | Private/MigrateEngineComponents.cpp 8 | Private/MigrateEngineComponents.h 9 | Private/MigrationRunner.cpp 10 | Private/MigrationRunner.h 11 | ) 12 | 13 | target_include_directories(EngineDatabaseMigrator 14 | PRIVATE 15 | ${CMAKE_CURRENT_SOURCE_DIR}/Private 16 | ) 17 | 18 | target_link_libraries(EngineDatabaseMigrator 19 | PRIVATE 20 | AmalgamEngine::SharedLib 21 | AmalgamEngine::ServerLib 22 | SQLiteCpp 23 | sqlite3 24 | ) 25 | 26 | # Compile with C++23. 27 | target_compile_features(EngineDatabaseMigrator PRIVATE cxx_std_23) 28 | set_target_properties(EngineDatabaseMigrator PROPERTIES CXX_EXTENSIONS OFF) 29 | 30 | # Enable compile warnings. 31 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 32 | target_compile_options(EngineDatabaseMigrator PUBLIC -Wall -Wextra) 33 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 34 | target_compile_options(EngineDatabaseMigrator PUBLIC /W3 /permissive-) 35 | endif() 36 | -------------------------------------------------------------------------------- /Source/Tools/EngineDatabaseMigrator/Private/MigrateEngineComponents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MigrationRunner.h" 4 | 5 | namespace SQLite 6 | { 7 | class Database; 8 | } 9 | 10 | namespace AM 11 | { 12 | namespace DM 13 | { 14 | 15 | class MigrateEngineComponents 16 | { 17 | public: 18 | /** 19 | * Migrates any engine entity components in the given database from 20 | * currentVersion to desiredVersion. 21 | */ 22 | static MigrationStatus migrate(SQLite::Database& database, 23 | unsigned int currentVersion, 24 | unsigned int desiredVersion); 25 | 26 | private: 27 | static void migrateV0ToV1(SQLite::Database& database); 28 | }; 29 | 30 | } // End namespace DM 31 | } // End namespace AM 32 | --------------------------------------------------------------------------------