diff --git a/lib/features/renderer/raycast_painter.dart b/lib/features/renderer/raycast_painter.dart index 3925144..910baf1 100644 --- a/lib/features/renderer/raycast_painter.dart +++ b/lib/features/renderer/raycast_painter.dart @@ -2,10 +2,8 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; -import 'package:wolf_dart/features/entities/pushwall_manager.dart'; -import 'package:wolf_dart/features/player/player.dart'; +import 'package:wolf_3d_engine/wolf_3d_engine.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; import 'package:wolf_dart/features/renderer/color_palette.dart'; class RaycasterPainter extends CustomPainter { diff --git a/lib/features/renderer/renderer.dart b/lib/features/renderer/renderer.dart index 3fe5bd4..63202f8 100644 --- a/lib/features/renderer/renderer.dart +++ b/lib/features/renderer/renderer.dart @@ -3,17 +3,8 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/collectible.dart'; -import 'package:wolf_dart/features/entities/door_manager.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; -import 'package:wolf_dart/features/entities/entity_registry.dart'; -import 'package:wolf_dart/features/entities/map_objects.dart'; -import 'package:wolf_dart/features/entities/pushwall_manager.dart'; -import 'package:wolf_dart/features/input/input_manager.dart'; -import 'package:wolf_dart/features/player/player.dart'; +import 'package:wolf_3d_engine/wolf_3d_engine.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; import 'package:wolf_dart/features/renderer/raycast_painter.dart'; import 'package:wolf_dart/features/renderer/weapon_painter.dart'; import 'package:wolf_dart/features/ui/hud.dart'; diff --git a/lib/features/screens/difficulty_screen.dart b/lib/features/screens/difficulty_screen.dart index 16c3bed..ff54bf5 100644 --- a/lib/features/screens/difficulty_screen.dart +++ b/lib/features/screens/difficulty_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; -import 'package:wolf_dart/features/difficulty/difficulty.dart'; import 'package:wolf_dart/features/renderer/renderer.dart'; import 'package:wolf_dart/wolf_3d.dart'; diff --git a/lib/features/ui/hud.dart b/lib/features/ui/hud.dart index bc2d515..38e2b16 100644 --- a/lib/features/ui/hud.dart +++ b/lib/features/ui/hud.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:wolf_dart/features/player/player.dart'; +import 'package:wolf_3d_engine/wolf_3d_engine.dart'; class Hud extends StatelessWidget { final Player player; diff --git a/lib/sprite_gallery.dart b/lib/sprite_gallery.dart index a3ce62d..5c4f3e4 100644 --- a/lib/sprite_gallery.dart +++ b/lib/sprite_gallery.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; import 'package:wolf_dart/features/renderer/color_palette.dart'; class SpriteGallery extends StatelessWidget { diff --git a/lib/classes/cardinal_direction.dart b/packages/wolf_3d_data_types/lib/src/cardinal_direction.dart similarity index 100% rename from lib/classes/cardinal_direction.dart rename to packages/wolf_3d_data_types/lib/src/cardinal_direction.dart diff --git a/lib/classes/coordinate_2d.dart b/packages/wolf_3d_data_types/lib/src/coordinate_2d.dart similarity index 100% rename from lib/classes/coordinate_2d.dart rename to packages/wolf_3d_data_types/lib/src/coordinate_2d.dart diff --git a/lib/features/difficulty/difficulty.dart b/packages/wolf_3d_data_types/lib/src/difficulty.dart similarity index 100% rename from lib/features/difficulty/difficulty.dart rename to packages/wolf_3d_data_types/lib/src/difficulty.dart diff --git a/lib/features/entities/map_objects.dart b/packages/wolf_3d_data_types/lib/src/map_objects.dart similarity index 96% rename from lib/features/entities/map_objects.dart rename to packages/wolf_3d_data_types/lib/src/map_objects.dart index 881dae1..beb3f4e 100644 --- a/lib/features/entities/map_objects.dart +++ b/packages/wolf_3d_data_types/lib/src/map_objects.dart @@ -1,6 +1,5 @@ -import 'package:wolf_dart/classes/cardinal_direction.dart'; -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; abstract class MapObject { // --- Player Spawns --- diff --git a/packages/wolf_3d_data_types/lib/wolf_3d_data_types.dart b/packages/wolf_3d_data_types/lib/wolf_3d_data_types.dart index 2b3d11b..defb0a7 100644 --- a/packages/wolf_3d_data_types/lib/wolf_3d_data_types.dart +++ b/packages/wolf_3d_data_types/lib/wolf_3d_data_types.dart @@ -3,10 +3,14 @@ /// More dartdocs go here. library; +export 'src/cardinal_direction.dart' show CardinalDirection; +export 'src/coordinate_2d.dart' show Coordinate2D; +export 'src/difficulty.dart' show Difficulty; export 'src/episode.dart' show Episode; export 'src/game_file.dart' show GameFile; export 'src/game_version.dart' show GameVersion; export 'src/image.dart' show VgaImage; +export 'src/map_objects.dart' show MapObject; export 'src/sound.dart' show PcmSound, AdLibSound, ImfMusic, ImfInstruction, WolfMusicMap; export 'src/sprite.dart' hide Matrix; diff --git a/packages/wolf_3d_data_types/pubspec.yaml b/packages/wolf_3d_data_types/pubspec.yaml index d541e72..534bcfb 100644 --- a/packages/wolf_3d_data_types/pubspec.yaml +++ b/packages/wolf_3d_data_types/pubspec.yaml @@ -8,6 +8,9 @@ environment: resolution: workspace +dependencies: + wolf_3d_entities: any + dev_dependencies: lints: ^6.0.0 test: ^1.25.6 diff --git a/packages/wolf_3d_engine/.gitignore b/packages/wolf_3d_engine/.gitignore new file mode 100644 index 0000000..3cceda5 --- /dev/null +++ b/packages/wolf_3d_engine/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/packages/wolf_3d_engine/CHANGELOG.md b/packages/wolf_3d_engine/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/packages/wolf_3d_engine/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/packages/wolf_3d_engine/README.md b/packages/wolf_3d_engine/README.md new file mode 100644 index 0000000..8831761 --- /dev/null +++ b/packages/wolf_3d_engine/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/wolf_3d_engine/analysis_options.yaml b/packages/wolf_3d_engine/analysis_options.yaml new file mode 100644 index 0000000..dee8927 --- /dev/null +++ b/packages/wolf_3d_engine/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/lib/features/input/input_manager.dart b/packages/wolf_3d_engine/lib/src/input/input_manager.dart similarity index 97% rename from lib/features/input/input_manager.dart rename to packages/wolf_3d_engine/lib/src/input/input_manager.dart index 31b7e50..a0bddc4 100644 --- a/lib/features/input/input_manager.dart +++ b/packages/wolf_3d_engine/lib/src/input/input_manager.dart @@ -1,5 +1,5 @@ import 'package:flutter/services.dart'; -import 'package:wolf_dart/features/weapon/weapon.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; class InputManager { Set _previousKeys = {}; diff --git a/lib/features/entities/door_manager.dart b/packages/wolf_3d_engine/lib/src/managers/door_manager.dart similarity index 96% rename from lib/features/entities/door_manager.dart rename to packages/wolf_3d_engine/lib/src/managers/door_manager.dart index 77a2052..babf81d 100644 --- a/lib/features/entities/door_manager.dart +++ b/packages/wolf_3d_engine/lib/src/managers/door_manager.dart @@ -1,7 +1,7 @@ import 'dart:math' as math; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; -import 'package:wolf_dart/features/entities/door.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; class DoorManager { // Key is '$x,$y' diff --git a/lib/features/entities/pushwall_manager.dart b/packages/wolf_3d_engine/lib/src/managers/pushwall_manager.dart similarity index 98% rename from lib/features/entities/pushwall_manager.dart rename to packages/wolf_3d_engine/lib/src/managers/pushwall_manager.dart index 502fb62..2fbfc2b 100644 --- a/lib/features/entities/pushwall_manager.dart +++ b/packages/wolf_3d_engine/lib/src/managers/pushwall_manager.dart @@ -1,7 +1,6 @@ import 'dart:math' as math; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; -import 'package:wolf_dart/features/entities/map_objects.dart'; class Pushwall { int x; diff --git a/lib/features/player/player.dart b/packages/wolf_3d_engine/lib/src/player/player.dart similarity index 91% rename from lib/features/player/player.dart rename to packages/wolf_3d_engine/lib/src/player/player.dart index f8b7307..cefee40 100644 --- a/lib/features/player/player.dart +++ b/packages/wolf_3d_engine/lib/src/player/player.dart @@ -1,15 +1,7 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/collectible.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; -import 'package:wolf_dart/features/entities/map_objects.dart'; -import 'package:wolf_dart/features/weapon/weapon.dart'; -import 'package:wolf_dart/features/weapon/weapons/chain_gun.dart'; -import 'package:wolf_dart/features/weapon/weapons/knife.dart'; -import 'package:wolf_dart/features/weapon/weapons/machine_gun.dart'; -import 'package:wolf_dart/features/weapon/weapons/pistol.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; enum WeaponSwitchState { idle, lowering, raising } diff --git a/packages/wolf_3d_engine/lib/src/wolf_3d_engine_base.dart b/packages/wolf_3d_engine/lib/src/wolf_3d_engine_base.dart new file mode 100644 index 0000000..9d6dc14 --- /dev/null +++ b/packages/wolf_3d_engine/lib/src/wolf_3d_engine_base.dart @@ -0,0 +1,349 @@ +// No flutter imports allowed! +import 'dart:math' as math; + +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_engine/wolf_3d_engine.dart'; +import 'package:wolf_3d_entities/wolf_3d_entities.dart'; + +class WolfEngine { + WolfEngine({ + required this.data, + required this.difficulty, + required this.startingEpisode, + required this.onGameWon, + }); + + final WolfensteinData data; + final Difficulty difficulty; + final int startingEpisode; + + // Standard Dart function instead of Flutter's VoidCallback + final void Function() onGameWon; + + // Managers + final InputManager inputManager = InputManager(); + final DoorManager doorManager = DoorManager(); + final PushwallManager pushwallManager = PushwallManager(); + + // State + late Player player; + late Level currentLevel; + late WolfLevel activeLevel; + List entities = []; + + int _currentEpisodeIndex = 0; + int _currentLevelIndex = 0; + int? _returnLevelIndex; + + double damageFlashOpacity = 0.0; + bool isInitialized = false; + + void init() { + _currentEpisodeIndex = startingEpisode; + _currentLevelIndex = 0; + _loadLevel(); + isInitialized = true; + } + + // Expect standard Dart Duration. The host app is responsible for the loop. + void tick(Duration elapsed) { + if (!isInitialized) return; + + final inputResult = _processInputs(elapsed); + + doorManager.update(elapsed); + pushwallManager.update(elapsed, currentLevel); + + player.updateWeaponSwitch(); + player.angle += inputResult.dAngle; + + if (player.angle < 0) player.angle += 2 * math.pi; + if (player.angle >= 2 * math.pi) player.angle -= 2 * math.pi; + + final Coordinate2D validatedPos = _calculateValidatedPosition( + player.position, + inputResult.movement, + ); + + player.x = validatedPos.x; + player.y = validatedPos.y; + + _updateEntities(elapsed); + + if (damageFlashOpacity > 0) { + damageFlashOpacity = math.max(0.0, damageFlashOpacity - 0.05); + } + + player.updateWeapon( + currentTime: elapsed.inMilliseconds, + entities: entities, + isWalkable: isWalkable, + ); + } + + void _loadLevel() { + entities.clear(); + damageFlashOpacity = 0.0; + + final episode = data.episodes[_currentEpisodeIndex]; + activeLevel = episode.levels[_currentLevelIndex]; + + currentLevel = List.generate(64, (y) => List.from(activeLevel.wallGrid[y])); + final Level objectLevel = activeLevel.objectGrid; + + doorManager.initDoors(currentLevel); + pushwallManager.initPushwalls(currentLevel, objectLevel); + + // TODO: Consider abstracting audio so the engine doesn't depend on Wolf3d singleton + Wolf3d.I.audio.playLevelMusic(activeLevel); + + for (int y = 0; y < 64; y++) { + for (int x = 0; x < 64; x++) { + int objId = objectLevel[y][x]; + + if (!MapObject.shouldSpawn(objId, difficulty)) continue; + + if (objId >= MapObject.playerNorth && objId <= MapObject.playerWest) { + double spawnAngle = 0.0; + if (objId == MapObject.playerNorth) { + spawnAngle = 3 * math.pi / 2; + } else if (objId == MapObject.playerEast) { + spawnAngle = 0.0; + } else if (objId == MapObject.playerSouth) { + spawnAngle = math.pi / 2; + } else if (objId == MapObject.playerWest) { + spawnAngle = math.pi; + } + + player = Player(x: x + 0.5, y: y + 0.5, angle: spawnAngle); + } else { + Entity? newEntity = EntityRegistry.spawn( + objId, + x + 0.5, + y + 0.5, + difficulty, + data.sprites.length, + isSharewareMode: data.version == GameVersion.shareware, + ); + if (newEntity != null) entities.add(newEntity); + } + } + } + + for (int y = 0; y < 64; y++) { + for (int x = 0; x < 64; x++) { + int id = currentLevel[y][x]; + if (!((id >= 1 && id <= 63) || (id >= 90 && id <= 101))) { + currentLevel[y][x] = 0; + } + } + } + + _bumpPlayerIfStuck(); + print("Loaded Floor: ${_currentLevelIndex + 1} - ${activeLevel.name}"); + } + + void _onLevelCompleted({bool isSecretExit = false}) { + Wolf3d.I.audio.stopMusic(); + + final currentEpisode = data.episodes[_currentEpisodeIndex]; + + if (isSecretExit) { + _returnLevelIndex = _currentLevelIndex + 1; + _currentLevelIndex = 9; + } else { + if (_currentLevelIndex == 9 && _returnLevelIndex != null) { + _currentLevelIndex = _returnLevelIndex!; + _returnLevelIndex = null; + } else { + _currentLevelIndex++; + } + } + + if (_currentLevelIndex >= currentEpisode.levels.length || + _currentLevelIndex > 9) { + print("Episode Completed! You win!"); + onGameWon(); + } else { + _loadLevel(); + } + } + + ({Coordinate2D movement, double dAngle}) _processInputs(Duration elapsed) { + inputManager.update(); + + const double moveSpeed = 0.14; + const double turnSpeed = 0.10; + + Coordinate2D movement = const Coordinate2D(0, 0); + double dAngle = 0.0; + + if (inputManager.requestedWeapon != null) { + player.requestWeaponSwitch(inputManager.requestedWeapon!); + } + + if (inputManager.isFiring) { + player.fire(elapsed.inMilliseconds); + } else { + player.releaseTrigger(); + } + + if (inputManager.isTurningLeft) dAngle -= turnSpeed; + if (inputManager.isTurningRight) dAngle += turnSpeed; + + Coordinate2D forwardVec = Coordinate2D( + math.cos(player.angle), + math.sin(player.angle), + ); + + if (inputManager.isMovingForward) movement += forwardVec * moveSpeed; + if (inputManager.isMovingBackward) movement -= forwardVec * moveSpeed; + + if (inputManager.isInteracting) { + int targetX = (player.x + math.cos(player.angle)).toInt(); + int targetY = (player.y + math.sin(player.angle)).toInt(); + + if (targetX >= 0 && targetX < 64 && targetY >= 0 && targetY < 64) { + int wallId = currentLevel[targetY][targetX]; + if (wallId == MapObject.normalElevatorSwitch) { + _onLevelCompleted(isSecretExit: false); + return (movement: const Coordinate2D(0, 0), dAngle: 0.0); + } else if (wallId == MapObject.secretElevatorSwitch) { + _onLevelCompleted(isSecretExit: true); + return (movement: const Coordinate2D(0, 0), dAngle: 0.0); + } + + int objId = activeLevel.objectGrid[targetY][targetX]; + if (objId == MapObject.normalExitTrigger) { + _onLevelCompleted(isSecretExit: false); + return (movement: movement, dAngle: dAngle); + } else if (objId == MapObject.secretExitTrigger) { + _onLevelCompleted(isSecretExit: true); + return (movement: movement, dAngle: dAngle); + } + } + + doorManager.handleInteraction(player.x, player.y, player.angle); + pushwallManager.handleInteraction( + player.x, + player.y, + player.angle, + currentLevel, + ); + } + + return (movement: movement, dAngle: dAngle); + } + + Coordinate2D _calculateValidatedPosition( + Coordinate2D currentPos, + Coordinate2D movement, + ) { + const double margin = 0.3; + double newX = currentPos.x; + double newY = currentPos.y; + + Coordinate2D target = currentPos + movement; + + if (movement.x != 0) { + int checkX = (movement.x > 0) + ? (target.x + margin).toInt() + : (target.x - margin).toInt(); + if (isWalkable(checkX, currentPos.y.toInt())) newX = target.x; + } + + if (movement.y != 0) { + int checkY = (movement.y > 0) + ? (target.y + margin).toInt() + : (target.y - margin).toInt(); + if (isWalkable(newX.toInt(), checkY)) newY = target.y; + } + + return Coordinate2D(newX, newY); + } + + void _updateEntities(Duration elapsed) { + List itemsToRemove = []; + List itemsToAdd = []; + + for (Entity entity in entities) { + if (entity is Enemy) { + final intent = entity.update( + elapsedMs: elapsed.inMilliseconds, + playerPosition: player.position, + isWalkable: isWalkable, + tryOpenDoor: doorManager.tryOpenDoor, + onDamagePlayer: (int damage) { + player.takeDamage(damage); + damageFlashOpacity = 0.5; + }, + ); + + entity.angle = intent.newAngle; + entity.x += intent.movement.x; + entity.y += intent.movement.y; + + if (entity.state == EntityState.dead && + entity.isDying && + !entity.hasDroppedItem) { + entity.hasDroppedItem = true; + Entity? droppedAmmo = EntityRegistry.spawn( + MapObject.ammoClip, + entity.x, + entity.y, + difficulty, + data.sprites.length, + ); + if (droppedAmmo != null) itemsToAdd.add(droppedAmmo); + } + } else if (entity is Collectible) { + if (player.position.distanceTo(entity.position) < 0.5) { + if (player.tryPickup(entity)) { + itemsToRemove.add(entity); + } + } + } + } + + if (itemsToRemove.isNotEmpty) { + entities.removeWhere((e) => itemsToRemove.contains(e)); + } + if (itemsToAdd.isNotEmpty) entities.addAll(itemsToAdd); + } + + bool isWalkable(int x, int y) { + if (currentLevel[y][x] == 0) return true; + if (currentLevel[y][x] >= 90) return doorManager.isDoorOpenEnough(x, y); + return false; + } + + void _bumpPlayerIfStuck() { + int pX = player.x.toInt(); + int pY = player.y.toInt(); + + if (pY < 0 || + pY >= currentLevel.length || + pX < 0 || + pX >= currentLevel[0].length || + currentLevel[pY][pX] > 0) { + double shortestDist = double.infinity; + Coordinate2D nearestSafeSpot = Coordinate2D(1.5, 1.5); + + for (int y = 0; y < currentLevel.length; y++) { + for (int x = 0; x < currentLevel[y].length; x++) { + if (currentLevel[y][x] == 0) { + Coordinate2D safeSpot = Coordinate2D(x + 0.5, y + 0.5); + double dist = safeSpot.distanceTo(player.position); + + if (dist < shortestDist) { + shortestDist = dist; + nearestSafeSpot = safeSpot; + } + } + } + } + player.x = nearestSafeSpot.x; + player.y = nearestSafeSpot.y; + } + } +} diff --git a/packages/wolf_3d_engine/lib/wolf_3d_engine.dart b/packages/wolf_3d_engine/lib/wolf_3d_engine.dart new file mode 100644 index 0000000..2b48325 --- /dev/null +++ b/packages/wolf_3d_engine/lib/wolf_3d_engine.dart @@ -0,0 +1,9 @@ +/// Support for doing something awesome. +/// +/// More dartdocs go here. +library; + +export 'src/managers/door_manager.dart'; +export 'src/managers/pushwall_manager.dart'; +export 'src/player/player.dart'; +export 'src/wolf_3d_engine_base.dart'; diff --git a/packages/wolf_3d_engine/pubspec.yaml b/packages/wolf_3d_engine/pubspec.yaml new file mode 100644 index 0000000..2c3c689 --- /dev/null +++ b/packages/wolf_3d_engine/pubspec.yaml @@ -0,0 +1,17 @@ +name: wolf_3d_engine +description: A starting point for Dart libraries or applications. +version: 1.0.0 +# repository: https://github.com/my_org/my_repo + +environment: + sdk: ^3.11.1 + +resolution: workspace + +dependencies: + wolf_3d_data_types: any + wolf_3d_entities: any + +dev_dependencies: + lints: ^6.0.0 + test: ^1.25.6 diff --git a/packages/wolf_3d_entities/.gitignore b/packages/wolf_3d_entities/.gitignore new file mode 100644 index 0000000..3cceda5 --- /dev/null +++ b/packages/wolf_3d_entities/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/packages/wolf_3d_entities/CHANGELOG.md b/packages/wolf_3d_entities/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/packages/wolf_3d_entities/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/packages/wolf_3d_entities/README.md b/packages/wolf_3d_entities/README.md new file mode 100644 index 0000000..8831761 --- /dev/null +++ b/packages/wolf_3d_entities/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/wolf_3d_entities/analysis_options.yaml b/packages/wolf_3d_entities/analysis_options.yaml new file mode 100644 index 0000000..dee8927 --- /dev/null +++ b/packages/wolf_3d_entities/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/lib/features/entities/collectible.dart b/packages/wolf_3d_entities/lib/src/entities/collectible.dart similarity index 91% rename from lib/features/entities/collectible.dart rename to packages/wolf_3d_entities/lib/src/entities/collectible.dart index e48e789..b241059 100644 --- a/lib/features/entities/collectible.dart +++ b/packages/wolf_3d_entities/lib/src/entities/collectible.dart @@ -1,5 +1,5 @@ -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; enum CollectibleType { ammo, health, treasure, weapon, key } diff --git a/lib/features/entities/decorative.dart b/packages/wolf_3d_entities/lib/src/entities/decorative.dart similarity index 92% rename from lib/features/entities/decorative.dart rename to packages/wolf_3d_entities/lib/src/entities/decorative.dart index 252e2c4..d75f698 100644 --- a/lib/features/entities/decorative.dart +++ b/packages/wolf_3d_entities/lib/src/entities/decorative.dart @@ -1,5 +1,5 @@ -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class Decorative extends Entity { Decorative({ diff --git a/lib/features/entities/door.dart b/packages/wolf_3d_entities/lib/src/entities/door.dart similarity index 100% rename from lib/features/entities/door.dart rename to packages/wolf_3d_entities/lib/src/entities/door.dart diff --git a/lib/features/entities/enemies/bosses/hans_grosse.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/bosses/hans_grosse.dart similarity index 90% rename from lib/features/entities/enemies/bosses/hans_grosse.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/bosses/hans_grosse.dart index cc7a6da..a180fad 100644 --- a/lib/features/entities/enemies/bosses/hans_grosse.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/bosses/hans_grosse.dart @@ -1,10 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; -import 'package:wolf_dart/features/entities/map_objects.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class HansGrosse extends Enemy { static const double speed = 0.04; @@ -17,10 +15,7 @@ class HansGrosse extends Enemy { required super.angle, required super.mapId, required Difficulty difficulty, - }) : super( - spriteIndex: _baseSprite, - state: EntityState.idle, - ) { + }) : super(spriteIndex: _baseSprite, state: EntityState.idle) { // Boss health scales heavily with difficulty health = switch (difficulty.level) { 0 => 850, diff --git a/lib/features/entities/enemies/dog.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/dog.dart similarity index 88% rename from lib/features/entities/enemies/dog.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/dog.dart index 7f2d52c..d370654 100644 --- a/lib/features/entities/enemies/dog.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/dog.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class Dog extends Enemy { static const double speed = 0.05; @@ -15,10 +15,7 @@ class Dog extends Enemy { required super.y, required super.angle, required super.mapId, - }) : super( - spriteIndex: type.spriteBaseIdx, - state: EntityState.idle, - ) { + }) : super(spriteIndex: type.spriteBaseIdx, state: EntityState.idle) { health = 1; damage = 5; } diff --git a/lib/features/entities/enemies/enemy.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/enemy.dart similarity index 93% rename from lib/features/entities/enemies/enemy.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/enemy.dart index d236ee3..2d64b3a 100644 --- a/lib/features/entities/enemies/enemy.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/enemy.dart @@ -1,39 +1,26 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/enemies/dog.dart'; -import 'package:wolf_dart/features/entities/enemies/guard.dart'; -import 'package:wolf_dart/features/entities/enemies/mutant.dart'; -import 'package:wolf_dart/features/entities/enemies/officer.dart'; -import 'package:wolf_dart/features/entities/enemies/ss.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; -import 'package:wolf_dart/features/entities/map_objects.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/dog.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/guard.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/mutant.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/officer.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/ss.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; -enum EnemyAnimation { - idle, - walking, - attacking, - pain, - dying, - dead, -} +enum EnemyAnimation { idle, walking, attacking, pain, dying, dead } enum EnemyType { guard(mapBaseId: 108, spriteBaseIdx: 50), dog(mapBaseId: 216, spriteBaseIdx: 99), ss(mapBaseId: 180, spriteBaseIdx: 138), mutant(mapBaseId: 252, spriteBaseIdx: 187), - officer(mapBaseId: 144, spriteBaseIdx: 238), - ; + officer(mapBaseId: 144, spriteBaseIdx: 238); final int mapBaseId; final int spriteBaseIdx; - const EnemyType({ - required this.mapBaseId, - required this.spriteBaseIdx, - }); + const EnemyType({required this.mapBaseId, required this.spriteBaseIdx}); /// Helper to check if a specific TED5 Map ID belongs to this enemy bool claimsMapId(int id) => id >= mapBaseId && id <= mapBaseId + 35; diff --git a/lib/features/entities/enemies/guard.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/guard.dart similarity index 88% rename from lib/features/entities/enemies/guard.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/guard.dart index 6fda7e4..3cf5ed7 100644 --- a/lib/features/entities/enemies/guard.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/guard.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class Guard extends Enemy { static const double speed = 0.03; @@ -15,10 +15,7 @@ class Guard extends Enemy { required super.y, required super.angle, required super.mapId, - }) : super( - spriteIndex: type.spriteBaseIdx, - state: EntityState.idle, - ); + }) : super(spriteIndex: type.spriteBaseIdx, state: EntityState.idle); @override ({Coordinate2D movement, double newAngle}) update({ diff --git a/lib/features/entities/enemies/mutant.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/mutant.dart similarity index 88% rename from lib/features/entities/enemies/mutant.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/mutant.dart index a932da7..8ef6b73 100644 --- a/lib/features/entities/enemies/mutant.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/mutant.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class Mutant extends Enemy { static const double speed = 0.04; @@ -15,10 +15,7 @@ class Mutant extends Enemy { required super.y, required super.angle, required super.mapId, - }) : super( - spriteIndex: type.spriteBaseIdx, - state: EntityState.idle, - ) { + }) : super(spriteIndex: type.spriteBaseIdx, state: EntityState.idle) { health = 45; damage = 10; } diff --git a/lib/features/entities/enemies/officer.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/officer.dart similarity index 95% rename from lib/features/entities/enemies/officer.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/officer.dart index abaf4b9..bf037ec 100644 --- a/lib/features/entities/enemies/officer.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/officer.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class Officer extends Enemy { static const double speed = 0.055; diff --git a/lib/features/entities/enemies/ss.dart b/packages/wolf_3d_entities/lib/src/entities/enemies/ss.dart similarity index 92% rename from lib/features/entities/enemies/ss.dart rename to packages/wolf_3d_entities/lib/src/entities/enemies/ss.dart index e85001b..830b43a 100644 --- a/lib/features/entities/enemies/ss.dart +++ b/packages/wolf_3d_entities/lib/src/entities/enemies/ss.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; class SS extends Enemy { static const double speed = 0.04; @@ -13,10 +13,7 @@ class SS extends Enemy { required super.y, required super.angle, required super.mapId, - }) : super( - spriteIndex: EnemyType.ss.spriteBaseIdx, - state: EntityState.idle, - ) { + }) : super(spriteIndex: EnemyType.ss.spriteBaseIdx, state: EntityState.idle) { health = 100; damage = 20; } diff --git a/lib/features/weapon/weapon.dart b/packages/wolf_3d_entities/lib/src/entities/weapon/weapon.dart similarity index 95% rename from lib/features/weapon/weapon.dart rename to packages/wolf_3d_entities/lib/src/entities/weapon/weapon.dart index b24608a..8e6abab 100644 --- a/lib/features/weapon/weapon.dart +++ b/packages/wolf_3d_entities/lib/src/entities/weapon/weapon.dart @@ -1,8 +1,8 @@ import 'dart:math' as math; -import 'package:wolf_dart/classes/coordinate_2d.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; enum WeaponState { idle, firing } diff --git a/lib/features/weapon/weapons/chain_gun.dart b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/chain_gun.dart similarity index 75% rename from lib/features/weapon/weapons/chain_gun.dart rename to packages/wolf_3d_entities/lib/src/entities/weapon/weapons/chain_gun.dart index 71b0053..add5c0e 100644 --- a/lib/features/weapon/weapons/chain_gun.dart +++ b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/chain_gun.dart @@ -1,4 +1,4 @@ -import 'package:wolf_dart/features/weapon/weapon.dart'; +import 'package:wolf_3d_entities/src/entities/weapon/weapon.dart'; class ChainGun extends Weapon { ChainGun() diff --git a/lib/features/weapon/weapons/knife.dart b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/knife.dart similarity index 87% rename from lib/features/weapon/weapons/knife.dart rename to packages/wolf_3d_entities/lib/src/entities/weapon/weapons/knife.dart index aeba056..6ff4a41 100644 --- a/lib/features/weapon/weapons/knife.dart +++ b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/knife.dart @@ -1,4 +1,4 @@ -import 'package:wolf_dart/features/weapon/weapon.dart'; +import 'package:wolf_3d_entities/src/entities/weapon/weapon.dart'; class Knife extends Weapon { Knife() diff --git a/lib/features/weapon/weapons/machine_gun.dart b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/machine_gun.dart similarity index 82% rename from lib/features/weapon/weapons/machine_gun.dart rename to packages/wolf_3d_entities/lib/src/entities/weapon/weapons/machine_gun.dart index 1743c3a..da880bb 100644 --- a/lib/features/weapon/weapons/machine_gun.dart +++ b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/machine_gun.dart @@ -1,4 +1,4 @@ -import 'package:wolf_dart/features/weapon/weapon.dart'; +import 'package:wolf_3d_entities/src/entities/weapon/weapon.dart'; class MachineGun extends Weapon { MachineGun() diff --git a/lib/features/weapon/weapons/pistol.dart b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/pistol.dart similarity index 76% rename from lib/features/weapon/weapons/pistol.dart rename to packages/wolf_3d_entities/lib/src/entities/weapon/weapons/pistol.dart index a6e99b0..49d076c 100644 --- a/lib/features/weapon/weapons/pistol.dart +++ b/packages/wolf_3d_entities/lib/src/entities/weapon/weapons/pistol.dart @@ -1,4 +1,4 @@ -import 'package:wolf_dart/features/weapon/weapon.dart'; +import 'package:wolf_3d_entities/src/entities/weapon/weapon.dart'; class Pistol extends Weapon { Pistol() diff --git a/lib/features/entities/entity.dart b/packages/wolf_3d_entities/lib/src/entity.dart similarity index 96% rename from lib/features/entities/entity.dart rename to packages/wolf_3d_entities/lib/src/entity.dart index fbdb85c..9bfd577 100644 --- a/lib/features/entities/entity.dart +++ b/packages/wolf_3d_entities/lib/src/entity.dart @@ -1,4 +1,4 @@ -import 'package:wolf_dart/classes/coordinate_2d.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; enum EntityState { staticObj, idle, patrolling, attacking, pain, dead } diff --git a/lib/features/entities/entity_registry.dart b/packages/wolf_3d_entities/lib/src/entity_registry.dart similarity index 78% rename from lib/features/entities/entity_registry.dart rename to packages/wolf_3d_entities/lib/src/entity_registry.dart index 488a5a2..ae09327 100644 --- a/lib/features/entities/entity_registry.dart +++ b/packages/wolf_3d_entities/lib/src/entity_registry.dart @@ -1,10 +1,9 @@ -import 'package:wolf_dart/features/difficulty/difficulty.dart'; -import 'package:wolf_dart/features/entities/collectible.dart'; -import 'package:wolf_dart/features/entities/decorative.dart'; -import 'package:wolf_dart/features/entities/enemies/bosses/hans_grosse.dart'; -import 'package:wolf_dart/features/entities/enemies/enemy.dart'; -import 'package:wolf_dart/features/entities/entity.dart'; -import 'package:wolf_dart/features/entities/map_objects.dart'; +import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; +import 'package:wolf_3d_entities/src/entities/collectible.dart'; +import 'package:wolf_3d_entities/src/entities/decorative.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/bosses/hans_grosse.dart'; +import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart'; +import 'package:wolf_3d_entities/src/entity.dart'; typedef EntitySpawner = Entity? Function( diff --git a/packages/wolf_3d_entities/lib/wolf_3d_entities.dart b/packages/wolf_3d_entities/lib/wolf_3d_entities.dart new file mode 100644 index 0000000..7862f13 --- /dev/null +++ b/packages/wolf_3d_entities/lib/wolf_3d_entities.dart @@ -0,0 +1,22 @@ +/// Support for doing something awesome. +/// +/// More dartdocs go here. +library; + +export 'src/entities/collectible.dart'; +export 'src/entities/decorative.dart'; +export 'src/entities/door.dart'; +export 'src/entities/enemies/bosses/hans_grosse.dart'; +export 'src/entities/enemies/dog.dart'; +export 'src/entities/enemies/enemy.dart'; +export 'src/entities/enemies/guard.dart'; +export 'src/entities/enemies/mutant.dart'; +export 'src/entities/enemies/officer.dart'; +export 'src/entities/enemies/ss.dart'; +export 'src/entities/weapon/weapon.dart'; +export 'src/entities/weapon/weapons/chain_gun.dart'; +export 'src/entities/weapon/weapons/knife.dart'; +export 'src/entities/weapon/weapons/machine_gun.dart'; +export 'src/entities/weapon/weapons/pistol.dart'; +export 'src/entity.dart'; +export 'src/entity_registry.dart'; diff --git a/packages/wolf_3d_entities/pubspec.yaml b/packages/wolf_3d_entities/pubspec.yaml new file mode 100644 index 0000000..436301a --- /dev/null +++ b/packages/wolf_3d_entities/pubspec.yaml @@ -0,0 +1,16 @@ +name: wolf_3d_entities +description: A starting point for Dart libraries or applications. +version: 1.0.0 +# repository: https://github.com/my_org/my_repo + +environment: + sdk: ^3.11.1 + +resolution: workspace + +dependencies: + wolf_3d_data_types: any + +dev_dependencies: + lints: ^6.0.0 + test: ^1.25.6 diff --git a/pubspec.yaml b/pubspec.yaml index d37576c..2f7e690 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,8 @@ dependencies: wolf_3d_data: any wolf_3d_data_types: any wolf_3d_synth: any + wolf_3d_engine: any + wolf_3d_entities: any flutter: sdk: flutter @@ -28,3 +30,5 @@ workspace: - packages/wolf_3d_data/ - packages/wolf_3d_data_types/ - packages/wolf_3d_synth/ + - packages/wolf_3d_engine/ + - packages/wolf_3d_entities/