From 6e48f0df224210f4ed92a0641b816c47a25dd570 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sun, 15 Mar 2026 15:08:37 -0400 Subject: [PATCH 01/19] Add submodules for OPResource + OPDB --- .gitmodules | 6 ++++++ asset | 1 + db | 1 + 3 files changed, 8 insertions(+) create mode 100644 .gitmodules create mode 160000 asset create mode 160000 db diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f5d7150 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "db"] + path = db + url = https://github.com/OpenPerpetuum/OPDB.git +[submodule "asset"] + path = asset + url = https://github.com/OpenPerpetuum/OPResource.git diff --git a/asset b/asset new file mode 160000 index 0000000..19b6b7f --- /dev/null +++ b/asset @@ -0,0 +1 @@ +Subproject commit 19b6b7f2c4455f8cd6b6fbac5f1b130683d23f45 diff --git a/db b/db new file mode 160000 index 0000000..008632e --- /dev/null +++ b/db @@ -0,0 +1 @@ +Subproject commit 008632ea4b20af45068e77c469e2ad5a3a4c0253 From 5af73813dae264f6f654b98aba57b3b5b8d0ce4c Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sun, 15 Mar 2026 15:34:50 -0400 Subject: [PATCH 02/19] Add container support using linux containers, add migration script for linux, add template for perpetuum.ini, add Makefile for some helper commands, update server to take DistributedTransactions as argument to be able to disable it for linux --- .env.local | 38 ++++++ Makefile | 36 ++++++ compose.yml | 85 ++++++++++++ docker/Dockerfile.asset.dev | 11 ++ docker/Dockerfile.migration.dev | 24 ++++ docker/Dockerfile.server.dev | 27 ++++ script/compose.sh | 8 ++ script/migration.sh | 122 ++++++++++++++++++ .../PerpetuumBootstrapper.cs | 4 +- .../PerpetuumServerService2.cs | 3 +- template/perpetuum.ini | 18 +++ template/restore_DB_to_original_state.sql | 17 +++ 12 files changed, 390 insertions(+), 3 deletions(-) create mode 100644 .env.local create mode 100644 Makefile create mode 100644 compose.yml create mode 100644 docker/Dockerfile.asset.dev create mode 100644 docker/Dockerfile.migration.dev create mode 100644 docker/Dockerfile.server.dev create mode 100755 script/compose.sh create mode 100755 script/migration.sh create mode 100644 template/perpetuum.ini create mode 100644 template/restore_DB_to_original_state.sql diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..0473f0d --- /dev/null +++ b/.env.local @@ -0,0 +1,38 @@ +# Environment for local development. +# Compatible with podman/docker with linux containers. + +# Database settings +DB_PASSWORD="l3 /migration/Patches/$1/$1.sql +} + +# Create perperuumsa database if it does not exist +echo "IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'perpetuumsa') CREATE DATABASE perpetuumsa" > /work/create-database.sql +/opt/mssql-tools/bin/sqlcmd -S db -C -U sa -P "${DB_PASSWORD}" -I -i "/work/create-database.sql" +rm /work/create-database.sql + +# echo "CREATE LOGIN sa WITH PASSWORD = '${DB_PASSWORD}'" > /work/create-user.sql +# runSqlCmd + +# Restore DB original state +runSqlCmd "/work/restore_DB_to_original_state.sql" + +# Apply patches +applyPatch Pre_Alpha_0 prealpha_patch_0.sql +applyPatch Pre_Alpha_1 prealpha_patch_1.sql Server +applyPatch Pre_Alpha_2 prealpha_patch_2.sql Server +applyPatch Pre_Alpha_3 prealpha_patch_3.sql +applyPatch Pre_Alpha_4 prealpha_patch_4.sql Server +applyPatch Pre_Alpha_5 prealpha_patch_5.sql +applyPatch Pre_Alpha_6 prealpha_patch_6.sql +applyPatch Pre_Alpha_7_FInal FIX_robottemplaterelation_pinkarkhe.sql +applyPatch Pre_Alpha_7_FInal NPC_robottemplates_argano_GetsEcms__2018_04_12.sql +applyPatch Live_1 live_patch_1.sql +applyPatch Live_2 live_patch_2.sql +applyPatch Live_3 live_patch_3.sql +applyPatch Live_4 live_patch_4.sql +applyPatch Live_5 live_patch_5.sql +applyPatch Live_6 live_patch_6.sql +applyPatch Live_7 live_patch_7.sql +applyPatch Live_8 live_patch_8.sql +applyPatch Live_9 live_patch_9.sql +applyPatch Live_10 live_patch_10.sql Server +applyPatch Live_11 live_patch_11.sql Server +applyPatch Live_12 live_patch_12.sql +applyPatch Live_13 live_patch_13.sql Server +applyPatch Live_14 live_patch_14.sql +applyPatch Live_15 live_patch_15.sql Server +applyPatch Live_16 live_patch_16.sql Server +applyPatch Live_17 live_patch_17.sql Server +applyPatch Live_18 live_patch_18.sql Server +applyPatch Live_19 live_patch_19.sql Server +applyPatch Live_20 live_patch_20.sql Server +applyPatch Live_21 live_patch_21.sql Server +applyPatch Live_22 live_patch_22.sql Server +applyPatch Live_23 live_patch_23.sql +applyPatch Live_24 live_patch_24.sql Server +applyPatch Live_25 live_patch_25.sql Server +applyPatch Live_26 live_patch_26.sql Server +applyPatch Live_27 live_patch_27.sql Server +applyPatch Live_28 live_patch_28.sql Server +applyPatch Live_29 live_patch_29.sql +applyPatch Live_30 live_patch_30.sql Server +applyPatch Live_31 live_patch_31.sql Server +applyPatch Live_32 live_patch_32.sql Server +applyPatch Live_33 live_patch_33.sql Server +preparePatch Live_34 +applyPatch Live_34 Live_34.sql Server +preparePatch Live_35 +applyPatch Live_35 Live_35.sql Server + + +# Add test account (user: test, pass: test) +runSqlCmd "/migration/Tools/TOOL_test_account.sql" + +echo Patching complete + +touch /data/done \ No newline at end of file diff --git a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs index 8717ade..d3fa67d 100644 --- a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs +++ b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs @@ -128,7 +128,7 @@ public void WriteCommandsToFile(string path) File.WriteAllText(path, sb.ToString()); } - public void Init(string gameRoot) + public void Init(string gameRoot, bool distributedTransactions) { _builder = new ContainerBuilder(); InitContainer(gameRoot); @@ -144,7 +144,7 @@ public void Init(string gameRoot) Logger.Info($"GC Latency mode: {GCSettings.LatencyMode}"); Logger.Info($"Vector is hardware accelerated: {Vector.IsHardwareAccelerated}"); - TransactionManager.ImplicitDistributedTransactions = true; + TransactionManager.ImplicitDistributedTransactions = distributedTransactions; Db.DbQueryFactory = _container.Resolve>(); diff --git a/src/Perpetuum.ServerService2/PerpetuumServerService2.cs b/src/Perpetuum.ServerService2/PerpetuumServerService2.cs index 1d4dd3e..9dc5630 100644 --- a/src/Perpetuum.ServerService2/PerpetuumServerService2.cs +++ b/src/Perpetuum.ServerService2/PerpetuumServerService2.cs @@ -23,11 +23,12 @@ public void ServerStart() { // assumes the server is in the default installation directory. string gameroot = _configuration.GetValue("GameRoot") ?? "C:\\PerpetuumServer\\data"; + bool distributedTransactions = _configuration.GetValue("DistributedTransactions", true); _logger.LogInformation("Perpetuum Dedicated Server v2 - starting"); try { - Bootstrapper.Init(gameroot); + Bootstrapper.Init(gameroot, distributedTransactions); } catch (Exception ex) { diff --git a/template/perpetuum.ini b/template/perpetuum.ini new file mode 100644 index 0000000..c4b180e --- /dev/null +++ b/template/perpetuum.ini @@ -0,0 +1,18 @@ +{ + "ListenerPort": {SERVER_PORT}, + "EnableUpnp": false, + "EnableDev": true, + + "PersonalConfig": "startup_standalone", + "ConnectionString": "{CONNECTION_STRING}", + + "Corporation":{ + "Price" : 250000, + "HangarPrice" : 50000, + "RentPeriod" : 7, + "LeavePeriod" : 1440, + "NumberOfHangarFolders" : 10, + "FoundingPrice" : 25000 + }, + "ResourceServerURL": "{ASSET_URL}" +} \ No newline at end of file diff --git a/template/restore_DB_to_original_state.sql b/template/restore_DB_to_original_state.sql new file mode 100644 index 0000000..8ec0c09 --- /dev/null +++ b/template/restore_DB_to_original_state.sql @@ -0,0 +1,17 @@ +-- Altered restore DB SQL script that can run inside a container +-- Assumes the 'perpetuumsa.bak' is available at the path '/data' + +USE [master] +GO + + +ALTER DATABASE perpetuumsa +SET SINGLE_USER WITH +ROLLBACK IMMEDIATE + +RESTORE DATABASE perpetuumsa FROM DISK = '/data/perpetuumsa.bak' WITH +MOVE 'perpetuumsa' TO '/data/psa.mdf', +MOVE 'perpetuumsa_log' TO '/data/psa_log.ldf', REPLACE + +ALTER DATABASE perpetuumsa SET MULTI_USER +GO \ No newline at end of file From 26512e64dbe14ddd31584ded04257519e31296f5 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sun, 15 Mar 2026 21:26:01 -0400 Subject: [PATCH 03/19] Update mssql-tools to a more recent version (18) to fix migration, update server image to include GDI+ --- docker/Dockerfile.migration.dev | 22 ++++++++++++++++++++-- docker/Dockerfile.server.dev | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docker/Dockerfile.migration.dev b/docker/Dockerfile.migration.dev index 74dc687..bd6bd07 100644 --- a/docker/Dockerfile.migration.dev +++ b/docker/Dockerfile.migration.dev @@ -1,10 +1,28 @@ -# TODO check for specific tag instead of latest if possible -FROM mcr.microsoft.com/mssql-tools:latest +FROM ubuntu:22.04 ARG ASSET_URL ARG CONNECTION_STRING ARG SERVER_PORT +# Install dependencies for mssql-tools18 +RUN apt-get update && apt-get install -y \ + curl \ + gnupg \ + apt-transport-https \ + && rm -rf /var/lib/apt/lists/* + +# Add Microsoft repository +RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \ + curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/msprod.list + +# Install mssql-tools18 +RUN apt-get update && ACCEPT_EULA=Y apt-get install -y \ + mssql-tools18 \ + && rm -rf /var/lib/apt/lists/* + +# Add sqlcmd to PATH +ENV PATH="/opt/mssql-tools18/bin:${PATH}" + WORKDIR /work COPY script/migration.sh . diff --git a/docker/Dockerfile.server.dev b/docker/Dockerfile.server.dev index b8449e8..62d698c 100644 --- a/docker/Dockerfile.server.dev +++ b/docker/Dockerfile.server.dev @@ -18,7 +18,10 @@ RUN dotnet publish --force src/Perpetuum.ServerService2/Perpetuum.ServerService2 FROM mcr.microsoft.com/dotnet/runtime-deps:10.0 # Install the missing GSSAPI/Kerberos dependency used by the SQL client -RUN apt-get update && apt-get install -y libgssapi-krb5-2 && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y libgssapi-krb5-2 curl && rm -rf /var/lib/apt/lists/* + +# Install GDI+ +RUN curl https://raw.githubusercontent.com/stulzq/awesome-dotnetcore-image/master/install/ubuntu.sh|sh WORKDIR /runtime From 0689ed4505ef0233ce2c4a093042110c8cacba62 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Mon, 16 Mar 2026 19:05:55 -0400 Subject: [PATCH 04/19] Fix comment in .env.local, remove preparePatch from the migration script and fix migration when using a directory --- .env.local | 3 +-- script/migration.sh | 33 ++++++++++++++++----------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/.env.local b/.env.local index 0473f0d..b2618f8 100644 --- a/.env.local +++ b/.env.local @@ -27,9 +27,8 @@ PERPETUUM_DATA="./perpetuum-data" # Connection string: Specific changes made to work on linux: # - Added "sa" user, password to use SQL server authentication; # - Added TrustServerCertificate=True to trust the self-signed certificate -# - Changed Server to the name of the db container: "db" +# - Changed Server to the name of the database container: "db" # - Removed due to incompatibility on linux: "Connection Reset=True;" -# - Removed since client refuses self-signed certificate: Trusted_Connection=True; # - Removed Trusted_Connection since we don't want to use Windows Authentication (SPPI) CONNECTION_STRING="Server=db;Database=perpetuumsa;User Id=sa;Password=${DB_PASSWORD};TrustServerCertificate=True;Pooling=True;Connection Timeout=30;Connection Lifetime=260;Min Pool Size=20;Max Pool Size=60;" diff --git a/script/migration.sh b/script/migration.sh index 7e0015a..cc94512 100755 --- a/script/migration.sh +++ b/script/migration.sh @@ -26,7 +26,9 @@ cp -rv /base-data/layers /data/ runSqlCmd () { set +x - /opt/mssql-tools/bin/sqlcmd -S db -d perpetuumsa -C -U sa -P "${DB_PASSWORD}" -I -i $1 + sqlcmd -S db -d perpetuumsa -C -U sa -P "${DB_PASSWORD}" -I -i $1 + # Comment the line above and uncomment the following line if you want to stop at any error during execution of a script. + # sqlcmd -S db -d perpetuumsa -b -C -U sa -P "${DB_PASSWORD}" -I -i $1 set -x } @@ -35,28 +37,27 @@ runSqlCmd () { # # Arguments: # - 1: Name of the directory of the patch to apply (Ex: Live_99) -# - 2: SQL File name to execute (Ex: some_patch.sql) +# - 2: SQL File name OR directory to execute (Ex: some_patch.sql or Raw_SQL) # - 3: (optional) Name of the directory containing the "data" folder (Ex: Server) applyPatch () { - runSqlCmd "/migration/Patches/$1/$2" + PATCH_PATH="/migration/Patches/$1/$2" + if [ -d "$PATCH_PATH" ]; then + for f in "$PATCH_PATH"/*.sql; do + [ -e "$f" ] || continue + runSqlCmd "$f" + done + else + runSqlCmd "$PATCH_PATH" + fi if [ $# -eq 3 ]; then cp -rv "/migration/Patches/$1/$3/data/" / fi } -# preparePatch concatenate all raw sql files into a single patch file. -# save the patch as "$1.sql" in the folder of the patch. -# -# Arguments: -# - 1: Name of the directory of the patch to prepare (Ex: Live_99) -preparePatch () { - cat /migration/Patches/$1/Raw_SQL/* > /migration/Patches/$1/$1.sql -} - # Create perperuumsa database if it does not exist echo "IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'perpetuumsa') CREATE DATABASE perpetuumsa" > /work/create-database.sql -/opt/mssql-tools/bin/sqlcmd -S db -C -U sa -P "${DB_PASSWORD}" -I -i "/work/create-database.sql" +sqlcmd -S db -C -U sa -P "${DB_PASSWORD}" -I -i "/work/create-database.sql" rm /work/create-database.sql # echo "CREATE LOGIN sa WITH PASSWORD = '${DB_PASSWORD}'" > /work/create-user.sql @@ -108,10 +109,8 @@ applyPatch Live_30 live_patch_30.sql Server applyPatch Live_31 live_patch_31.sql Server applyPatch Live_32 live_patch_32.sql Server applyPatch Live_33 live_patch_33.sql Server -preparePatch Live_34 -applyPatch Live_34 Live_34.sql Server -preparePatch Live_35 -applyPatch Live_35 Live_35.sql Server +applyPatch Live_34 Raw_SQL Server +applyPatch Live_35 Raw_SQL Server # Add test account (user: test, pass: test) From 1073ced618d551b25799dd9b886ad8c55b84ca4f Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Mon, 16 Mar 2026 20:03:34 -0400 Subject: [PATCH 05/19] Move db persistent storage into a docker volume --- compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compose.yml b/compose.yml index 2ba7373..78f93c8 100644 --- a/compose.yml +++ b/compose.yml @@ -29,9 +29,8 @@ services: hostname: db volumes: # Note for linux/WSL2, it can cause permission denied, fix: - # mkdir mssql-data - # sudo chown -R 10001:10001 mssql-data - - ./mssql-data:/var/opt/mssql + # sudo chown -R 10001:10001 openperpetuum-db + - openperpetuum-db:/var/opt/mssql # Mount perpetuum database path that contains the perpetuumsa.bak - "${PERPETUUM_DATA}/database:/data" @@ -82,4 +81,5 @@ networks: driver: bridge volumes: - openperpetuum-data: \ No newline at end of file + openperpetuum-data: + openperpetuum-db: \ No newline at end of file From 0fa79c68c4fa8275d77112f71d690064727be94d Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Fri, 20 Mar 2026 20:11:39 -0400 Subject: [PATCH 06/19] Most fo the refactor from System.Drawing to SkiaSharp is done. --- .env.local | 10 +- .gitignore | 8 + Makefile | 2 +- compose.yml | 4 +- docker/Dockerfile.migration.dev | 4 +- docker/Dockerfile.server.dev | 5 +- script/migration.sh | 9 +- .../Modules/TerrainsModule.cs | 3 +- .../Perpetuum.RequestHandlers.csproj | 1 + src/Perpetuum.RequestHandlers/SetRobotTint.cs | 5 +- .../NpcPlaceSafeSpawnPoint.cs | 4 +- .../NpcSafeSpawnPointRequestHandler.cs | 5 +- .../NpcSetSafeSpawnPoint.cs | 4 +- .../Zone/StatsMapDrawing/DisplaySpots.cs | 6 +- .../StatsMapDrawing/DrawMissionTargetLog.cs | 114 +++++---- .../StatsMapDrawing/GenerateMissionSpots.cs | 113 ++++---- .../GenerateRandomPointsOnly.cs | 7 +- .../ValidateMissionObjectLocations.cs | 29 ++- .../Zone/StatsMapDrawing/WorstMissionSpots.cs | 27 +- .../Zone/StatsMapDrawing/ZoneDrawStatMap.cs | 241 ++++++++++-------- .../Zone/ZoneSetLayerWithBitMap.cs | 10 +- src/Perpetuum.Server/Program.cs | 3 +- src/Perpetuum/Area.cs | 20 +- src/Perpetuum/BinaryStream.cs | 12 +- src/Perpetuum/BitmapExtensions.cs | 11 +- .../Collections/Spatial/Grid.NonGeneric.cs | 7 +- src/Perpetuum/Collections/Spatial/Grid.cs | 10 +- src/Perpetuum/Collections/Spatial/QuadTree.cs | 5 +- src/Perpetuum/ColorExtensions.cs | 17 ++ src/Perpetuum/Commands.cs | 4 +- src/Perpetuum/EnumerableExtensions.cs | 3 - src/Perpetuum/GenXY/GenxyConverter.cs | 18 +- src/Perpetuum/GenXY/GenxyReader.cs | 10 +- src/Perpetuum/Items/Paint.cs | 9 +- src/Perpetuum/Modules/DrillerModule.cs | 4 +- src/Perpetuum/Modules/LargeHarvesterModule.cs | 2 +- src/Perpetuum/PathFinders/AStarFinder.cs | 17 +- src/Perpetuum/PathFinders/PathFinder.cs | 16 +- src/Perpetuum/Perpetuum.csproj | 3 +- src/Perpetuum/Players/PlayerMoveChecker.cs | 5 +- src/Perpetuum/PointExtensions.cs | 50 ++-- src/Perpetuum/Robots/Robot.Properties.cs | 16 +- .../MissionEngine/MissionSpotObjects.cs | 7 +- .../ZoneMissionTargetObjects.cs | 68 +++-- .../RelicManagers/AbstractRelicManager.cs | 14 +- .../RelicManagers/OutpostRelicManager.cs | 11 +- .../Relics/RelicManagers/ZoneRelicManager.cs | 4 +- .../Services/RiftSystem/RiftManager.cs | 15 +- src/Perpetuum/SizeExtensions.cs | 22 +- src/Perpetuum/StateMachines/IState.cs | 2 - src/Perpetuum/Zones/Artifacts/Artifact.cs | 4 +- .../Generators/PersistentArtifactGenerator.cs | 7 +- .../Artifacts/Scanners/ArtifactScanResult.cs | 4 +- .../Artifacts/Scanners/ArtifactScanner.cs | 2 - src/Perpetuum/Zones/Beams/BeamBuilder.cs | 5 +- .../RandomWalkableAroundPositionFinder.cs | 2 +- src/Perpetuum/Zones/IZone.cs | 6 +- src/Perpetuum/Zones/Movements/PathMovement.cs | 7 +- src/Perpetuum/Zones/NpcSystem/AI/BaseAI.cs | 3 - src/Perpetuum/Zones/NpcSystem/AI/CombatAI.cs | 20 +- .../AI/CombatDrones/CombatDroneAI.cs | 20 +- .../AI/CombatDrones/EscortCombatDroneAI.cs | 3 +- .../AI/CombatDrones/RetreatCombatDroneAI.cs | 4 +- src/Perpetuum/Zones/NpcSystem/AI/HomingAI.cs | 6 +- .../Zones/NpcSystem/AI/IndustrialAI.cs | 25 +- .../EscortIndustrialDroneAI.cs | 4 +- .../RetreatIndustrialDroneAI.cs | 4 +- src/Perpetuum/Zones/NpcSystem/AI/Node.cs | 7 +- .../NpcSystem/Presences/DynamicPresence.cs | 5 +- .../RandomSpawningExpiringPresence.cs | 5 +- .../InterzonePresences/InterzonePresence.cs | 7 +- .../PathFinders/FreeRoamingPathFinder.cs | 15 +- .../PathFinders/IRoamingPathFinder.cs | 6 +- .../PathFinders/NormalRoamingPathFinder.cs | 19 +- .../Presences/PathFinders/RoamingState.cs | 2 - .../Presences/PresenceConfiguration.cs | 2 +- .../NpcSystem/Presences/RoamingPresence.cs | 8 +- .../ISafeSpawnPointsRepository.cs | 2 - .../NpcSafeSpawnPointsRepository.cs | 6 +- .../SafeSpawnPoints/SafeSpawnPoint.cs | 5 +- .../Zones/PBS/EnergyWell/PBSEnergyWell.cs | 8 +- src/Perpetuum/Zones/Position.cs | 30 +-- .../Scanning/Scanners/Scanner.Artifact.cs | 4 +- .../Scanning/Scanners/Scanner.Directional.cs | 10 +- .../Scanning/Scanners/Scanner.Intrusion.cs | 4 +- .../Scanning/Scanners/Scanner.OneTile.cs | 7 +- src/Perpetuum/Zones/Terrains/BlockingInfo.cs | 2 - src/Perpetuum/Zones/Terrains/ITerrain.cs | 1 - .../Zones/Terrains/IUpdateableLayer.cs | 2 - .../Zones/Terrains/LayerExtensions.cs | 5 +- .../Generators/MineralNodeGeneratorBase.cs | 17 +- .../RandomWalkMineralNodeGenerator.cs | 18 +- .../Materials/Minerals/GravelLayer.cs | 14 +- .../Materials/Minerals/MineralExtractor.cs | 14 +- .../Materials/Minerals/MineralLayer.cs | 14 +- .../Materials/Minerals/MineralNode.cs | 17 +- .../Terrains/Materials/Plants/PlantHandler.cs | 6 +- .../Zones/Terrains/PassableMapBuilder.cs | 9 +- .../Operations/BlurTerraformingOperation.cs | 4 +- .../Terrains/Terraforming/TerraformHandler.cs | 9 +- src/Perpetuum/Zones/Terrains/Terrain.cs | 1 - .../Zones/Terrains/TerrainUpdateMonitor.cs | 11 +- .../Zones/Terrains/TerrainUpdateNotifier.cs | 6 +- src/Perpetuum/Zones/Zone.cs | 4 +- src/Perpetuum/Zones/ZoneConfiguration.cs | 11 +- src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs | 25 +- src/Perpetuum/Zones/ZoneExtensions.Terrain.cs | 10 +- src/Perpetuum/Zones/ZoneExtensions.cs | 24 +- .../{perpetuum.ini => perpetuum.ini.template} | 0 109 files changed, 730 insertions(+), 768 deletions(-) create mode 100644 src/Perpetuum/ColorExtensions.cs rename template/{perpetuum.ini => perpetuum.ini.template} (100%) diff --git a/.env.local b/.env.local index b2618f8..97d026b 100644 --- a/.env.local +++ b/.env.local @@ -21,9 +21,17 @@ ASSET_URL="http://localhost:${ASSET_PORT}" GAME_ROOT="/data" -# Directory from the official PerpetuumServer data +# Original data directory from Stream: Perpetuum Dedicated Server installer PERPETUUM_DATA="./perpetuum-data" +# User-provided additional map layers assets +# TODO: Move to a guide/readme +# Required if you want to load the server with Gamma Islands +# Download URL: https://drive.google.com/file/d/1qDjPHbTSdal_aKN6SvYC_EoGW-COkwhJ/view?usp=sharing +# sha256sum: +# f4d42d5dbf6a61d2d7730b2058f5d2bb80a63d0994bbc84b906f19441bb8e425 GAMMA_LAYERS_2021_10_17_P26.rar +CUSTOM_LAYERS="./custom-layers" + # Connection string: Specific changes made to work on linux: # - Added "sa" user, password to use SQL server authentication; # - Added TrustServerCertificate=True to trust the self-signed certificate diff --git a/.gitignore b/.gitignore index 48a955f..8aca2a8 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,11 @@ src/Perpetuum.ServerService2/data/layers/ src/Perpetuum.ServerService2/data/logs/ bin/ Releases/ + +custom-assets/ + +# User-provided additional map layers assets +custom-layers/ + +# Original directory folder from Stream: Perpetuum Dedicated Server installer +perpetuum-data/ diff --git a/Makefile b/Makefile index 2a0a076..4722989 100644 --- a/Makefile +++ b/Makefile @@ -33,4 +33,4 @@ log-db: log-server: ./script/compose.sh logs server -f -phonyx: help compose-start compose-stop compose-down log-asset log-db log-server +phonyx: help up start stop down log-asset log-db log-server diff --git a/compose.yml b/compose.yml index 78f93c8..97f3ea3 100644 --- a/compose.yml +++ b/compose.yml @@ -53,6 +53,8 @@ services: volumes: - ./db:/migration - "${PERPETUUM_DATA}:/base-data" + - "${CUSTOM_LAYERS}:/custom-layers" + - "./src/Perpetuum.ServerService2/data:/perpetuum-service-data" - openperpetuum-data:/data server: @@ -82,4 +84,4 @@ networks: volumes: openperpetuum-data: - openperpetuum-db: \ No newline at end of file + openperpetuum-db: diff --git a/docker/Dockerfile.migration.dev b/docker/Dockerfile.migration.dev index bd6bd07..12007a4 100644 --- a/docker/Dockerfile.migration.dev +++ b/docker/Dockerfile.migration.dev @@ -26,9 +26,11 @@ ENV PATH="/opt/mssql-tools18/bin:${PATH}" WORKDIR /work COPY script/migration.sh . -COPY template/perpetuum.ini . +COPY template/perpetuum.ini.template . COPY template/restore_DB_to_original_state.sql . +RUN mv perpetuum.ini.template perpetuum.ini + RUN sed -i "s/{SERVER_PORT}/${SERVER_PORT}/" perpetuum.ini # Update the connection string but hides the command to hide the password RUN set +x && \ diff --git a/docker/Dockerfile.server.dev b/docker/Dockerfile.server.dev index 62d698c..d210461 100644 --- a/docker/Dockerfile.server.dev +++ b/docker/Dockerfile.server.dev @@ -9,7 +9,10 @@ WORKDIR /build COPY src ./src/ -# Build the projectt (restore + compile) +# Dedicated restore command to cache the layer for faster container boot time= +RUN dotnet restore src/Perpetuum.ServerService2/Perpetuum.ServerService2.csproj + +# Build the project # Provides a self-contained executable (no dotnet runtime required) RUN dotnet publish --force src/Perpetuum.ServerService2/Perpetuum.ServerService2.csproj --configuration Release --self-contained --runtime $RUNTIME_IDENTIFIER -o out diff --git a/script/migration.sh b/script/migration.sh index cc94512..d6da288 100755 --- a/script/migration.sh +++ b/script/migration.sh @@ -19,11 +19,18 @@ set -eux # - Set initial state using backup # - Run migration for each patch +# Copy the generated perpetuum.ini cp -v /work/perpetuum.ini /data/ # Copy PerpetuumServer/data to the shared /data cp -rv /base-data/layers /data/ +# Copy the custom-layers to the shared /data/layers +cp -rv /custom-layers/* /data/layers + +# Copy the Perpetuum.ServerService data directory +cp -rv /perpetuum-service-data/* /data/ + runSqlCmd () { set +x sqlcmd -S db -d perpetuumsa -C -U sa -P "${DB_PASSWORD}" -I -i $1 @@ -118,4 +125,4 @@ runSqlCmd "/migration/Tools/TOOL_test_account.sql" echo Patching complete -touch /data/done \ No newline at end of file +touch /data/done diff --git a/src/Perpetuum.Bootstrapper/Modules/TerrainsModule.cs b/src/Perpetuum.Bootstrapper/Modules/TerrainsModule.cs index 531fb52..28b71a9 100644 --- a/src/Perpetuum.Bootstrapper/Modules/TerrainsModule.cs +++ b/src/Perpetuum.Bootstrapper/Modules/TerrainsModule.cs @@ -11,6 +11,7 @@ using Perpetuum.Zones.Terrains.Materials.Minerals; using Perpetuum.Zones.Terrains.Materials.Minerals.Generators; using Perpetuum.Zones.Terrains.Materials.Plants; +using SkiaSharp; namespace Perpetuum.Bootstrapper.Modules { @@ -88,7 +89,7 @@ protected override void Load(ContainerBuilder builder) { Terrain terrain = ctx.Resolve(); - System.Drawing.Size size = zone.Configuration.Size; + SKSizeI size = zone.Configuration.Size; ILayerFileIO loader = ctx.Resolve(); diff --git a/src/Perpetuum.RequestHandlers/Perpetuum.RequestHandlers.csproj b/src/Perpetuum.RequestHandlers/Perpetuum.RequestHandlers.csproj index 47de154..bca53b0 100644 --- a/src/Perpetuum.RequestHandlers/Perpetuum.RequestHandlers.csproj +++ b/src/Perpetuum.RequestHandlers/Perpetuum.RequestHandlers.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Perpetuum.RequestHandlers/SetRobotTint.cs b/src/Perpetuum.RequestHandlers/SetRobotTint.cs index 6e5046f..cfe3345 100644 --- a/src/Perpetuum.RequestHandlers/SetRobotTint.cs +++ b/src/Perpetuum.RequestHandlers/SetRobotTint.cs @@ -1,8 +1,7 @@ -using System.Collections.Generic; -using System.Drawing; using Perpetuum.Data; using Perpetuum.Host.Requests; using Perpetuum.Robots; +using SkiaSharp; namespace Perpetuum.RequestHandlers { @@ -13,7 +12,7 @@ public void HandleRequest(IRequest request) using (var scope = Db.CreateTransaction()) { var robotEid = request.Data.GetOrDefault(k.robotEID); - var tint = request.Data.GetOrDefault(k.tint); + var tint = request.Data.GetOrDefault(k.tint); var robot = Robot.GetOrThrow(robotEid); robot.Tint = tint; diff --git a/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcPlaceSafeSpawnPoint.cs b/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcPlaceSafeSpawnPoint.cs index fd4b3a2..67924c0 100644 --- a/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcPlaceSafeSpawnPoint.cs +++ b/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcPlaceSafeSpawnPoint.cs @@ -1,6 +1,6 @@ -using System.Drawing; using Perpetuum.Data; using Perpetuum.Host.Requests; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.NpcSafeSpawnPoints { @@ -12,7 +12,7 @@ public override void HandleRequest(IZoneRequest request) { var x = request.Data.GetOrDefault(k.x); var y = request.Data.GetOrDefault(k.y); - AddSafeSpawnPoint(request, new Point(x, y)); + AddSafeSpawnPoint(request, new SKPointI(x, y)); scope.Complete(); } } diff --git a/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSafeSpawnPointRequestHandler.cs b/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSafeSpawnPointRequestHandler.cs index be954eb..484b717 100644 --- a/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSafeSpawnPointRequestHandler.cs +++ b/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSafeSpawnPointRequestHandler.cs @@ -1,9 +1,8 @@ -using System.Collections.Generic; -using System.Drawing; using System.Transactions; using Perpetuum.Data; using Perpetuum.Host.Requests; using Perpetuum.Zones.NpcSystem.SafeSpawnPoints; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.NpcSafeSpawnPoints { @@ -36,7 +35,7 @@ void Sender() } } - protected void AddSafeSpawnPoint(IZoneRequest request, Point location) + protected void AddSafeSpawnPoint(IZoneRequest request, SKPointI location) { var point = new SafeSpawnPoint { Location = location }; request.Zone.SafeSpawnPoints.Add(point); diff --git a/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSetSafeSpawnPoint.cs b/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSetSafeSpawnPoint.cs index 1030e74..386fe1f 100644 --- a/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSetSafeSpawnPoint.cs +++ b/src/Perpetuum.RequestHandlers/Zone/NpcSafeSpawnPoints/NpcSetSafeSpawnPoint.cs @@ -1,7 +1,7 @@ -using System.Drawing; using Perpetuum.Data; using Perpetuum.Host.Requests; using Perpetuum.Zones.NpcSystem.SafeSpawnPoints; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.NpcSafeSpawnPoints { @@ -18,7 +18,7 @@ public override void HandleRequest(IZoneRequest request) var point = new SafeSpawnPoint { Id = id, - Location = new Point(x, y) + Location = new SKPointI(x, y) }; request.Zone.SafeSpawnPoints.Update(point); diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DisplaySpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DisplaySpots.cs index 37cb22c..851b6f8 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DisplaySpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DisplaySpots.cs @@ -1,11 +1,11 @@ -using System.Drawing; -using Perpetuum.Services.MissionEngine; +using Perpetuum.Services.MissionEngine; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.StatsMapDrawing { public partial class ZoneDrawStatMap { - private Bitmap DisplaySpots() + private SKBitmap DisplaySpots() { var staticObjects = MissionSpot.GetStaticObjectsFromZone(_zone); diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs index 55a1440..ed3fd36 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs @@ -1,17 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using System.Data; using Perpetuum.Data; using Perpetuum.Host.Requests; using Perpetuum.Log; using Perpetuum.Services.MissionEngine; using Perpetuum.Services.MissionEngine.MissionStructures; using Perpetuum.Zones; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.StatsMapDrawing { @@ -70,7 +64,7 @@ private void DrawMissionTargetLog(IRequest request) internal class MissionTargetSuccessLogEntry { public DateTime EventTime; - public Point point; + public SKPoint point; public MissionTargetType targetType; public Guid guid; public long locationEid; @@ -82,7 +76,7 @@ public static MissionTargetSuccessLogEntry FromRecord(IDataRecord record) var mtsle = new MissionTargetSuccessLogEntry() { EventTime = record.GetValue("eventtime"), - point = new Point(record.GetValue("x"), record.GetValue("y")), + point = new SKPointI(record.GetValue("x"), record.GetValue("y")), targetType = (MissionTargetType) record.GetValue("targettype"), guid = record.GetValue("guid"), locationEid = record.GetValue("locationeid"), @@ -121,8 +115,10 @@ private void DrawOneCategory(IRequest request,MissionLocation missionLocation, M var category1 = category; - bitmap.WithGraphics(gx => gx.DrawString(category1.ToString(), new Font("Tahoma", 15), new SolidBrush(Color.White), new PointF(20, 40))); - bitmap.WithGraphics(gx => gx.DrawString(littleText, new Font("Tahoma", 15), new SolidBrush(Color.White), new PointF(20, 60))); + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 15); + var paint = new SKPaint { Color = SKColors.White }; + bitmap.WithCanvas(gx => gx.DrawText(category1.ToString(), 20, 40, font, paint)); + bitmap.WithCanvas(gx => gx.DrawText(littleText, 20, 60, font, paint)); var idString = $"{missionLocation.id:0000}"; @@ -131,35 +127,33 @@ private void DrawOneCategory(IRequest request,MissionLocation missionLocation, M _saveBitmapHelper.SaveBitmap(_zone,bitmap, fname); } - private void DrawEntriesOnBitmap(MissionTargetSuccessLogEntry[] entries, Bitmap background) + private void DrawEntriesOnBitmap(MissionTargetSuccessLogEntry[] entries, SKBitmap background) { var eventSeries = entries.GroupBy(t => t.guid); - var g = Graphics.FromImage(background); - var pen = new Pen(new SolidBrush(Color.FromArgb(25, Color.FromArgb(200, 200, 200))), 1.1f); - - var switchBrush = new SolidBrush(Color.FromArgb(25, _switchColor)); - var submitItemBrush = new SolidBrush(Color.FromArgb(25, _kioskColor)); - var itemSupplyBrush = new SolidBrush(Color.FromArgb(25, _itemSupplyColor)); - var findArtifactBrush = new SolidBrush(Color.FromArgb(50, _findArtifactColor)); - var popNpcBrush = new SolidBrush(Color.FromArgb(50, _popNpcColor)); - var lootBrush = new SolidBrush(Color.FromArgb(50, _lootColor)); - var fetchItemBrush = new SolidBrush(Color.FromArgb(25, _fetchItemColor)); - var killBrush = new SolidBrush(Color.FromArgb(30, _killColor)); - var scanMineralBrush = new SolidBrush(Color.FromArgb(50, _scanMineralColor)); - var drillMineralBrush = new SolidBrush(Color.FromArgb(50, _drillMineralColor)); - var harvestBrush = new SolidBrush(Color.FromArgb(50, _harvestColor)); + var c = new SKCanvas(background); + var pen = new SKPaint { Color = new SKColor(200, 200, 200, 25), Style = SKPaintStyle.Stroke, StrokeWidth = 1.1f, IsAntialias = true }; + + var switchBrush = new SKPaint { Color = new SKColor(_switchColor.Red, _switchColor.Green, _switchColor.Blue, 25), IsAntialias = true }; + var submitItemBrush = new SKPaint { Color = new SKColor(_kioskColor.Red, _kioskColor.Green, _kioskColor.Blue, 25), Style = SKPaintStyle.Fill, IsAntialias = true }; + var itemSupplyBrush = new SKPaint { Color = new SKColor(_itemSupplyColor.Red, _itemSupplyColor.Green, _itemSupplyColor.Blue, 25), Style = SKPaintStyle.Fill, IsAntialias = true }; + var findArtifactBrush = new SKPaint { Color = new SKColor(_findArtifactColor.Red, _findArtifactColor.Green, _findArtifactColor.Blue, 50), Style = SKPaintStyle.Fill, IsAntialias = true }; + var popNpcBrush = new SKPaint { Color = new SKColor(_popNpcColor.Red, _popNpcColor.Green, _popNpcColor.Blue, 50), Style = SKPaintStyle.Fill, IsAntialias = true }; + var lootBrush = new SKPaint { Color = new SKColor(_lootColor.Red, _lootColor.Green, _lootColor.Blue, 50), Style = SKPaintStyle.Stroke, IsAntialias = true }; + var fetchItemBrush = new SKPaint { Color = new SKColor(_fetchItemColor.Red, _fetchItemColor.Green, _fetchItemColor.Blue, 25), Style = SKPaintStyle.Fill, IsAntialias = true }; + var killBrush = new SKPaint { Color = new SKColor(_killColor.Red, _killColor.Green, _killColor.Blue, 30), Style = SKPaintStyle.Fill, IsAntialias = true }; + var scanMineralBrush = new SKPaint { Color = new SKColor(_scanMineralColor.Red, _scanMineralColor.Green, _scanMineralColor.Blue, 50), Style = SKPaintStyle.Fill, IsAntialias = true }; + var drillMineralBrush = new SKPaint { Color = new SKColor(_drillMineralColor.Red, _drillMineralColor.Green, _drillMineralColor.Blue, 50), Style = SKPaintStyle.Fill, IsAntialias = true }; + var harvestBrush = new SKPaint { Color = new SKColor(_harvestColor.Red, _harvestColor.Green, _harvestColor.Blue, 50), Style = SKPaintStyle.Stroke, IsAntialias = true }; var circle = 10.0f; - g.CompositingQuality = CompositingQuality.HighQuality; - g.SmoothingMode = SmoothingMode.AntiAlias; foreach (var series in eventSeries) { var points = series.OrderBy(v => v.EventTime).Select(v => v.point).ToArray(); - g.DrawLines(pen, points); + c.DrawPoints(SKPointMode.Polygon, points, pen); var eventsAtStructures = series.Where(s => ( s.targetType == MissionTargetType.use_switch || @@ -177,66 +171,76 @@ private void DrawEntriesOnBitmap(MissionTargetSuccessLogEntry[] entries, Bitmap foreach (var logEntry in eventsAtStructures) { - Brush p; - Pen pp; + SKPaint paint; switch (logEntry.targetType) { case MissionTargetType.submit_item: - p = submitItemBrush; - g.FillEllipse(p, logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + paint = submitItemBrush; + SKRect rect = new(logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + c.DrawOval(rect, paint); continue; case MissionTargetType.use_switch: - p = switchBrush; - g.FillEllipse(p, logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + paint = switchBrush; + rect = new(logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + c.DrawOval(rect, paint); continue; case MissionTargetType.use_itemsupply: - p = itemSupplyBrush; - g.FillEllipse(p, logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + paint = itemSupplyBrush; + rect = new(logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + c.DrawOval(rect, paint); continue; case MissionTargetType.find_artifact: - p = findArtifactBrush; - g.FillRectangle(p, logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + paint = findArtifactBrush; + rect = new(logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + c.DrawOval(rect, paint); continue; case MissionTargetType.pop_npc: - p = popNpcBrush; - g.FillRectangle(p, logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + paint = popNpcBrush; + rect = new(logEntry.point.X - circle / 2.0f, logEntry.point.Y - circle / 2.0f, circle, circle); + c.DrawOval(rect, paint); continue; case MissionTargetType.loot_item: - pp = new Pen(lootBrush, 3); + paint = lootBrush; const int lootSize = 11; - g.DrawRectangle(pp, logEntry.point.X - lootSize / 2.0f, logEntry.point.Y - lootSize / 2.0f, lootSize, lootSize); + rect = new(logEntry.point.X - lootSize / 2.0f, logEntry.point.Y - lootSize / 2.0f, lootSize, lootSize); + c.DrawOval(rect, paint); continue; case MissionTargetType.fetch_item: - pp = new Pen(fetchItemBrush, 4); + paint = fetchItemBrush; const int fetchSize = 14; - g.DrawRectangle(pp, logEntry.point.X - fetchSize / 2.0f, logEntry.point.Y - fetchSize / 2.0f, fetchSize, fetchSize); + rect = new(logEntry.point.X - fetchSize / 2.0f, logEntry.point.Y - fetchSize / 2.0f, fetchSize, fetchSize); + c.DrawOval(rect, paint); continue; case MissionTargetType.kill_definition: const int tizenKetto = 12; - pp = new Pen(killBrush, 4); - g.DrawRectangle(pp, logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + rect = new(logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + paint = killBrush; + c.DrawRect(rect, paint); continue; case MissionTargetType.scan_mineral: - pp = new Pen(scanMineralBrush, 4); - g.DrawEllipse(pp, logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + paint = scanMineralBrush; + rect = new(logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + c.DrawOval(rect, paint); continue; case MissionTargetType.drill_mineral: - pp = new Pen(drillMineralBrush, 4); - g.DrawEllipse(pp, logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + paint = drillMineralBrush; + rect = new(logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + c.DrawOval(rect, paint); continue; case MissionTargetType.harvest_plant: - pp = new Pen(harvestBrush, 4); - g.DrawEllipse(pp, logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + paint = harvestBrush; + rect = new(logEntry.point.X - tizenKetto / 2.0f, logEntry.point.Y - tizenKetto / 2.0f, tizenKetto, tizenKetto); + c.DrawOval(rect, paint ); continue; default: @@ -254,7 +258,7 @@ private void DrawEntriesOnBitmap(MissionTargetSuccessLogEntry[] entries, Bitmap - private Bitmap DrawAllTargetsOnZone() + private SKBitmap DrawAllTargetsOnZone() { const string query = "SELECT * FROM dbo.missiontargetslog WHERE zoneid=@zoneId"; diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs index cd380e5..0ba7d62 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs @@ -1,15 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Linq; -using System.Threading.Tasks; -using Perpetuum.Data; +using Perpetuum.Data; using Perpetuum.Host.Requests; using Perpetuum.Log; using Perpetuum.Services.MissionEngine; using Perpetuum.Zones; using Perpetuum.Zones.Terrains; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.StatsMapDrawing { @@ -143,7 +138,7 @@ private class AccuracyInfo private const int structureToTerminals = 50; private const int randomPointToTerminals = 70; - private Bitmap GenerateMissionSpots(IRequest request) + private SKBitmap GenerateMissionSpots(IRequest request) { //-------- kick brute force fill in @@ -176,26 +171,26 @@ private Bitmap GenerateMissionSpots(IRequest request) return resultBitmap; } - private static readonly Color _passableColor = Color.FromArgb(255,16, 26, 26); - private static readonly Color _fieldTerminalColor = Color.White; - private static readonly Color _switchColor = Color.FromArgb(255,255, 82, 0); - private static readonly Color _kioskColor = Color.FromArgb(255,153, 206, 70); - private static readonly Color _itemSupplyColor = Color.FromArgb(255,48, 198, 249); - private static readonly Color _randomPointColor = Color.FromArgb(255,237, 144, 251); - private static readonly Color _dockingBaseColor = Color.FromArgb(255,21, 68, 29); - private static readonly Color _teleportColor = Color.FromArgb(255,74, 78, 6); - private static readonly Color _sapColor = Color.FromArgb(255,54, 29, 99); - private static readonly Color _islandColor = Color.FromArgb(255,0, 24, 59); - private static readonly Color _findArtifactColor = Color.FromArgb(255,255, 204, 77); - private static readonly Color _popNpcColor = Color.FromArgb(255, 105, 82, 0); - private static readonly Color _lootColor = Color.FromArgb(255, 0, 151, 208); - private static readonly Color _fetchItemColor = Color.FromArgb(255, 12, 137, 119); - private static readonly Color _killColor = Color.FromArgb(255, 152, 15, 15); - private static readonly Color _scanMineralColor = Color.FromArgb(255, 124, 164, 255); - private static readonly Color _drillMineralColor = Color.FromArgb(255, 214, 144, 126); - private static readonly Color _harvestColor = Color.FromArgb(255, 164, 231, 72); - - private Bitmap DrawResultOnBitmap(List spotInfos, Dictionary> staticObjects ) + private static readonly SKColor _passableColor = new(16, 26, 26); + private static readonly SKColor _fieldTerminalColor = SKColors.White; + private static readonly SKColor _switchColor = new(255, 82, 0); + private static readonly SKColor _kioskColor = new(153, 206, 70); + private static readonly SKColor _itemSupplyColor = new(48, 198, 249); + private static readonly SKColor _randomPointColor = new(237, 144, 251); + private static readonly SKColor _dockingBaseColor = new(21, 68, 29); + private static readonly SKColor _teleportColor = new(74, 78, 6); + private static readonly SKColor _sapColor = new(54, 29, 99); + private static readonly SKColor _islandColor = new(0, 24, 59); + private static readonly SKColor _findArtifactColor = new(255, 204, 77); + private static readonly SKColor _popNpcColor = new(105, 82, 0); + private static readonly SKColor _lootColor = new(0, 151, 208); + private static readonly SKColor _fetchItemColor = new(12, 137, 119); + private static readonly SKColor _killColor = new(152, 15, 15); + private static readonly SKColor _scanMineralColor = new(124, 164, 255); + private static readonly SKColor _drillMineralColor = new(214, 144, 126); + private static readonly SKColor _harvestColor = new(164, 231, 72); + + private SKBitmap DrawResultOnBitmap(List spotInfos, Dictionary> staticObjects ) { var b = _zone.CreatePassableBitmap(_passableColor); @@ -227,23 +222,23 @@ private Bitmap DrawResultOnBitmap(List spotInfos, Dictionary spotInfos, Dictionary g.DrawString(fttext, new Font("Tahoma", 15), new SolidBrush(_fieldTerminalColor), new PointF(20, 40))); - b.WithGraphics(g => g.DrawString(swtext, new Font("Tahoma", 15), new SolidBrush(_switchColor), new PointF(20, 60))); - b.WithGraphics(g => g.DrawString(kiotext, new Font("Tahoma", 15), new SolidBrush(_kioskColor), new PointF(20, 80))); - b.WithGraphics(g => g.DrawString(istext, new Font("Tahoma", 15), new SolidBrush(_itemSupplyColor), new PointF(20, 100))); - b.WithGraphics(g => g.DrawString(rptext, new Font("Tahoma", 15), new SolidBrush(_randomPointColor), new PointF(20, 120))); + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 15); + var fieldTerminalColorPaint = new SKPaint { Color = _fieldTerminalColor }; + var switchPaint = new SKPaint { Color = _switchColor }; + var kioskPaint = new SKPaint { Color = _kioskColor }; + var itemSupplyPaint = new SKPaint { Color = _itemSupplyColor }; + var randomPointPaint = new SKPaint { Color = _randomPointColor }; + + b.WithCanvas(c => c.DrawText(fttext, 20, 40, font, fieldTerminalColorPaint)); + b.WithCanvas(c => c.DrawText(swtext, 20, 60, font, switchPaint)); + b.WithCanvas(c => c.DrawText(kiotext, 20, 80, font, kioskPaint)); + b.WithCanvas(c => c.DrawText(istext, 20, 100, font, itemSupplyPaint)); + b.WithCanvas(c => c.DrawText(rptext, 20, 120, font, randomPointPaint)); return b; } - private void FillEllipseOnPoint(Color color, int radius, Position position, Bitmap bitmap) + private void FillEllipseOnPoint(SKColor color, int radius, Position position, SKBitmap bitmap) { - var gfx = Graphics.FromImage(bitmap); - gfx.CompositingQuality = CompositingQuality.HighQuality; - gfx.SmoothingMode = SmoothingMode.AntiAlias; + var c = new SKCanvas(bitmap); var size = radius * 2; var x = position.intX - radius; var y = position.intY - radius; - gfx.FillEllipse(new SolidBrush(color),x,y,size,size ); + var paint = new SKPaint { Color = color, Style = SKPaintStyle.Fill, IsAntialias = true }; + var rect = new SKRect(x,y,size,size); + c.DrawOval(rect, paint); /* @@ -306,18 +308,17 @@ private void FillEllipseOnPoint(Color color, int radius, Position position, Bitm } - private void DrawEllipseOnPoint(Color color, int radius, Position position, Bitmap bitmap) + private void DrawEllipseOnPoint(SKColor color, int radius, Position position, SKBitmap bitmap) { - var gfx = Graphics.FromImage(bitmap); - gfx.CompositingQuality = CompositingQuality.HighQuality; - gfx.SmoothingMode = SmoothingMode.AntiAlias; + var c = new SKCanvas(bitmap); var size = radius * 2; var x = position.intX - radius; var y = position.intY - radius; - gfx.DrawEllipse( new Pen(color,3), x, y, size, size); - + var paint = new SKPaint { Color = color, Style = SKPaintStyle.Stroke, StrokeWidth = 3, IsAntialias = true }; + var rect = new SKRect(x, y, size, size); + c.DrawOval(rect, paint); } @@ -335,7 +336,7 @@ private void PlaceOneType(List spotInfos, MissionSpotType type, int var currentBorder = accuracyInfo.initialBorder; var foundTotal = 0; - var freePoints = new List(_zone.Configuration.Size.Width * _zone.Configuration.Size.Height); + var freePoints = new List(_zone.Configuration.Size.Width * _zone.Configuration.Size.Height); InitPoints(spotInfos, distanceInfos, staticObjects, freePoints); while (true) @@ -421,7 +422,7 @@ private static void SaveInfoAsync(MissionSpot si) Task.Run(() => { si.Save(); }); } - private void InitPoints(List spotInfos, Dictionary distanceInfos, Dictionary> staticObjects, List freePoints) + private void InitPoints(List spotInfos, Dictionary distanceInfos, Dictionary> staticObjects, List freePoints) { var zoneWidth = _zone.Size.Width; var zoneHeight = _zone.Size.Height; @@ -437,16 +438,16 @@ private void InitPoints(List spotInfos, Dictionary freePoints) + private static void CleanUpOneSpot(Position center, int distance, ref List freePoints) { - var goodKeys = new List(freePoints.Count); + var goodKeys = new List(freePoints.Count); foreach (var point in freePoints) { var pos = point.ToPosition(); @@ -583,9 +584,9 @@ private bool CheckConditionsAroundPosition(Position center, int blockRadius, int private int _counter; - private void MakeASnapshot(MissionSpotType spotType, List freePoints) + private void MakeASnapshot(MissionSpotType spotType, List freePoints) { - var pointsCopy = new List(freePoints); + var pointsCopy = new List(freePoints); _counter++; var fileName = spotType + "_freepoints." + $"{_counter:0000}"; @@ -596,7 +597,7 @@ private void MakeASnapshot(MissionSpotType spotType, List freePoints) foreach (var point in pointsCopy) { - bmp.SetPixel(point.X, point.Y, Color.White); + bmp.SetPixel(point.X, point.Y, SKColors.White); } _saveBitmapHelper.SaveBitmap(_zone,bmp, fileName); diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateRandomPointsOnly.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateRandomPointsOnly.cs index d49d6a0..7e4f911 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateRandomPointsOnly.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateRandomPointsOnly.cs @@ -1,17 +1,16 @@ -using System.Drawing; -using System.Linq; -using Perpetuum.Data; +using Perpetuum.Data; using Perpetuum.Host.Requests; using Perpetuum.Log; using Perpetuum.Services.MissionEngine; using Perpetuum.Zones; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.StatsMapDrawing { public partial class ZoneDrawStatMap { - private Bitmap GenerateRandomPointsOnly(IRequest request) + private SKBitmap GenerateRandomPointsOnly(IRequest request) { //-------- kick brute force fill in const int randomPointTargetAmount = 2500; diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ValidateMissionObjectLocations.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ValidateMissionObjectLocations.cs index 0757398..facbd43 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ValidateMissionObjectLocations.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ValidateMissionObjectLocations.cs @@ -1,11 +1,10 @@ -using System.Drawing; -using System.Linq; -using Perpetuum.Log; +using Perpetuum.Log; using Perpetuum.Services.MissionEngine; using Perpetuum.Services.MissionEngine.MissionStructures; using Perpetuum.Units.DockingBases; using Perpetuum.Units.FieldTerminals; using Perpetuum.Zones; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.StatsMapDrawing { @@ -13,18 +12,18 @@ public partial class ZoneDrawStatMap { - public Bitmap ValidateMissionObjectLocations() + public SKBitmap ValidateMissionObjectLocations() { var b = _zone.CreatePassableBitmap(_passableColor); - var g = Graphics.FromImage(b); + var c = new SKCanvas(b); var circle = 10f; var randomPointTargets = _missionDataCache.GetAllMissionTargets.Where(t => t.ZoneId == _zone.Id && t.Type == MissionTargetType.rnd_point).ToList(); - var greebrush = new SolidBrush(Color.LawnGreen); - var redBrush = new SolidBrush(Color.OrangeRed); - var yellowBrush = new SolidBrush(Color.Yellow); - var redPen = new Pen(Color.Red, 4); + var greenbrush = new SKPaint { Color = SKColors.LawnGreen, Style = SKPaintStyle.Fill }; + var redBrush = new SKPaint { Color = SKColors.OrangeRed, Style = SKPaintStyle.Fill }; + var yellowBrush = new SKPaint { Color = SKColors.Yellow, Style = SKPaintStyle.Fill }; + var redPen = new SKPaint { Color = SKColors.Red, Style = SKPaintStyle.Stroke, StrokeWidth = 4 }; foreach (var randomPointTarget in randomPointTargets) { @@ -32,11 +31,13 @@ public Bitmap ValidateMissionObjectLocations() if (CheckConditionsAroundPosition(p, randomPointBlockRadius, randomPointIslandRadius, true)) { - g.FillEllipse(greebrush,(float)( randomPointTarget.targetPosition.X - circle ), (float)( randomPointTarget.targetPosition.Y - circle ), circle*2, circle*2); + var rect = new SKRect((float)(randomPointTarget.targetPosition.X - circle), (float)(randomPointTarget.targetPosition.Y - circle), circle * 2, circle * 2); + c.DrawOval(rect, greenbrush); } else { - g.FillEllipse(redBrush, (float)(randomPointTarget.targetPosition.X - circle ), (float)(randomPointTarget.targetPosition.Y - circle ), circle*2, circle*2); + var rect = new SKRect((float)(randomPointTarget.targetPosition.X - circle ), (float)(randomPointTarget.targetPosition.Y - circle ), circle*2, circle*2); + c.DrawOval(rect, redBrush); } } @@ -50,7 +51,8 @@ public Bitmap ValidateMissionObjectLocations() if (strucureTarget == null) { Logger.Error("no target was found for structure:" + structureUnit.Eid + " " + structureUnit.TargetType); - g.FillEllipse(yellowBrush, structureUnit.CurrentPosition.intX - circle, structureUnit.CurrentPosition.intY - circle, circle*2, circle*2); + var rect = new SKRect(structureUnit.CurrentPosition.intX - circle, structureUnit.CurrentPosition.intY - circle, circle*2, circle*2); + c.DrawOval(rect, yellowBrush); continue; } @@ -68,7 +70,8 @@ public Bitmap ValidateMissionObjectLocations() if (location == null) { - g.DrawEllipse(redPen, locationUnit.CurrentPosition.intX - circle, locationUnit.CurrentPosition.intY - circle, circle * 2, circle * 2); + var rect = new SKRect(locationUnit.CurrentPosition.intX - circle, locationUnit.CurrentPosition.intY - circle, circle * 2, circle * 2); + c.DrawOval(rect, redPen); Logger.Error("no location was found for " + locationUnit); continue; } diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs index 8f1b063..f8d563f 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs @@ -1,17 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using Perpetuum.Log; +using Perpetuum.Log; using Perpetuum.Services.MissionEngine; using Perpetuum.Zones; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone.StatsMapDrawing { public partial class ZoneDrawStatMap { - private Bitmap DrawWorstSpotsMap() + private SKBitmap DrawWorstSpotsMap() { _addtoradius = 0; //init the mf var b = _zone.CreatePassableBitmap(_passableColor, _islandColor); @@ -35,11 +32,15 @@ private Bitmap DrawWorstSpotsMap() WriteReportByType(MissionSpotType.kiosk, spotStats,b); WriteReportByType(MissionSpotType.itemsupply, spotStats,b); - - b.WithGraphics(g => g.DrawString("switch", new Font("Tahoma", 15), new SolidBrush(_switchColor), new PointF(20, 60))); - b.WithGraphics(g => g.DrawString("item submit/kiosk", new Font("Tahoma", 15), new SolidBrush(_kioskColor), new PointF(20, 80))); - b.WithGraphics(g => g.DrawString("item supply", new Font("Tahoma", 15), new SolidBrush(_itemSupplyColor), new PointF(20, 100))); - b.WithGraphics(g => g.DrawString("random point", new Font("Tahoma", 15), new SolidBrush(_randomPointColor), new PointF(20, 120))); + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 15); + var switchPaint = new SKPaint { Color = _switchColor }; + var kioskPaint = new SKPaint { Color = _kioskColor }; + var itemSupplyPaint = new SKPaint { Color = _itemSupplyColor }; + var randomPointPaint = new SKPaint { Color = _randomPointColor }; + b.WithCanvas(c => c.DrawText("switch", 20, 60, font, switchPaint)); + b.WithCanvas(c => c.DrawText("item submit/kiosk", 20, 80, font, kioskPaint)); + b.WithCanvas(c => c.DrawText("item supply", 20, 100, font, itemSupplyPaint)); + b.WithCanvas(c => c.DrawText("random point", 20, 120, font, randomPointPaint)); return b; @@ -47,7 +48,7 @@ private Bitmap DrawWorstSpotsMap() } private int _addtoradius; - private void WriteReportByType(MissionSpotType missionSpotType, List spotStats, Bitmap bitmap) + private void WriteReportByType(MissionSpotType missionSpotType, List spotStats, SKBitmap bitmap) { var lines = new List(spotStats.Count); var ordered = spotStats.OrderBy(s => s.GetAmountByType(missionSpotType)).ToArray(); @@ -72,7 +73,7 @@ private void WriteReportByType(MissionSpotType missionSpotType, List _zone.CreatePassableBitmap(Color.White)); + RegisterCreator("passable", () => _zone.CreatePassableBitmap(SKColors.White)); RegisterCreator("islandmask", CreateIslandMaskMap); RegisterCreator("controlmap", CreateControlMap); RegisterCreator("TerraformProtected", CreateControlFlagMap(TerrainControlFlags.TerraformProtected)); @@ -74,31 +73,33 @@ public ZoneDrawStatMap(IFileSystem fileSystem, SaveBitmapHelper saveBitmapHelper RegisterCreator(k.groundType, CreateGroundTypeMap); } - private void RegisterCreator(string type, Func bitmapFactory) + private void RegisterCreator(string type, Func bitmapFactory) { _actions[type] = (r) => CreateAndSave(type, () => bitmapFactory(r)); } - private void RegisterCreator(string type, Func bitmapFactory) + private void RegisterCreator(string type, Func bitmapFactory) { _actions[type] = (r) => CreateAndSave(type, bitmapFactory); } - private void CreateAndSave(string postfix, Func bitmapFactory) + private void CreateAndSave(string postfix, Func bitmapFactory) { - Bitmap bmp = bitmapFactory(); + SKBitmap bmp = bitmapFactory(); if (bmp == null) { return; } - bmp.WithGraphics(g => g.DrawString(_zone.Configuration.Name, new Font("Tahoma", 20), Brushes.Red, new PointF(10, 10))); + var paint = new SKPaint { Color = SKColors.Red }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 20); + bmp.WithCanvas(c => c.DrawText(_zone.Configuration.Name, 10, 10, font, paint)); string fileName = "stat_" + postfix; if (_sendtoclient) // send to client. { using MemoryStream ms = new(); - bmp.Save(ms, ImageFormat.Png); + bmp.Encode(ms, SKEncodedImageFormat.Png, 100); string Base64 = Convert.ToBase64String(ms.GetBuffer()); Message.Builder.FromRequest(_request).SetData("name", fileName).SetData("img", Base64).Send(); } @@ -251,17 +252,17 @@ public void HandleRequest(IZoneRequest request) Message.Builder.FromRequest(request).WithData(data).Send(); } - private Bitmap CreateAltitudeBitmap() + private SKBitmap CreateAltitudeBitmap() { return _zone.CreateBitmap().ForEach((bmp, x, y) => { byte altitudeValue = (byte)(_zone.Terrain.Altitude.GetAltitudeAsDouble(x, y) / 2048 * 612).Clamp(0, 255); - Color color = Color.FromArgb(altitudeValue, altitudeValue, altitudeValue); + SKColor color = new(altitudeValue, altitudeValue, altitudeValue); bmp.SetPixel(x, y, color); }); } - private Bitmap CreateSlopeBitmap() + private SKBitmap CreateSlopeBitmap() { const int threshold = 4 * 4; @@ -275,12 +276,12 @@ private Bitmap CreateSlopeBitmap() return; } - int c = 255 - (int)((double)slope / threshold * 255); - bmp.SetPixel(x, y, Color.FromArgb(c, c, c)); + byte c = (byte)(255 - (int)((double)slope / threshold * 255)); + bmp.SetPixel(x, y, new(c, c, c)); }); } - private Bitmap CreateBlockingMap() + private SKBitmap CreateBlockingMap() { return _zone.CreateBitmap().ForEach((bmp, x, y) => { @@ -290,7 +291,7 @@ private Bitmap CreateBlockingMap() return; } - bmp.SetPixel(x, y, Color.White); + bmp.SetPixel(x, y, SKColors.White); }); } @@ -300,15 +301,15 @@ private void GenerateNewFlagsMap() } - private Bitmap CreateNewFlagsMap() + private SKBitmap CreateNewFlagsMap() { return _zone.CreateBitmap().ForEach((bmp, x, y) => { TerrainControlInfo ci = _zone.Terrain.Controls.GetValue(x, y); - int r = 0; - int g = 0; - int b = 0; + byte r = 0; + byte g = 0; + byte b = 0; if (ci.PBSHighway) { @@ -325,51 +326,59 @@ private Bitmap CreateNewFlagsMap() b = 255; } - Color color = Color.FromArgb(255, r, g, b); + SKColor color = new(r, g, b); bmp.SetPixel(x, y, color); }); } - private Bitmap CreatePlayersMap() + private SKBitmap CreatePlayersMap() { - return CreateAltitudeBitmap().WithGraphics(g => + return CreateAltitudeBitmap().WithCanvas(c => { foreach (Accounting.Characters.Character unit in _zone.GetCharacters()) { int size = 12; - Pen pen = Pens.Red; int x = unit.GetPlayerRobotFromZone().CurrentPosition.intX - (size / 2); int y = unit.GetPlayerRobotFromZone().CurrentPosition.intY - (size / 2); - g.DrawEllipse(pen, x, y, size, size); + var pen = new SKPaint { Color = SKColors.Red, Style = SKPaintStyle.Stroke }; + var rect1 = new SKRectI(x, y, size, size); + c.DrawOval(rect1, pen); const int width = 4; - g.DrawEllipse(Pens.BlueViolet, x, y, width, width); - g.DrawString(unit.Nick, new Font("Tahoma", 12), Brushes.Red, x + 10, y + 10); + var pen2 = new SKPaint { Color = SKColors.BlueViolet, Style = SKPaintStyle.Stroke }; + var rect2 = new SKRectI(x, y, width, width); + c.DrawOval(rect2, pen2); + var textPaint = new SKPaint { Color = SKColors.Red }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 12); + c.DrawText(unit.Nick, x + 10, y + 10, font, textPaint); } }); } - private Bitmap CreateNPCMap() + private SKBitmap CreateNPCMap() { - return CreateAltitudeBitmap().WithGraphics(g => + return CreateAltitudeBitmap().WithCanvas(g => { DrawNpcPresencesOnGraphic(g); DrawNpcFlocksOnGraphic(g); }); } - private void DrawNpcPresencesOnGraphic(Graphics graphics) + private void DrawNpcPresencesOnGraphic(SKCanvas canvas) { foreach (RoamingPresence presence in _zone.PresenceManager.GetPresences().OfType()) { - graphics.DrawRectangle(Pens.Blue, presence.Area.X1, presence.Area.Y1, presence.Area.Width, presence.Area.Height); - graphics.DrawString(presence.Configuration.Name, new Font("Tahoma", 8), Brushes.Red, presence.Area.X1, presence.Area.Y1); + var paint = new SKPaint { Color = SKColors.Blue, Style = SKPaintStyle.Stroke }; + canvas.DrawRect(presence.Area.X1, presence.Area.Y1, presence.Area.Width, presence.Area.Height, paint); + var textPaint = new SKPaint { Color = SKColors.Red }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 8); + canvas.DrawText(presence.Configuration.Name, presence.Area.X1, presence.Area.Y1, font, textPaint); } } - private void DrawNpcFlocksOnGraphic(Graphics graphics) + private void DrawNpcFlocksOnGraphic(SKCanvas canvas) { foreach (Zones.NpcSystem.Flocks.Flock? flock in _zone.PresenceManager.GetPresences().OfType().SelectMany(p => p.Flocks)) { @@ -381,18 +390,24 @@ private void DrawNpcFlocksOnGraphic(Graphics graphics) int tyHomeRange = flock.Configuration.SpawnOrigin.intY - flock.HomeRange; int widthHome = flock.HomeRange * 2; - graphics.DrawEllipse(Pens.BlueViolet, txSpawnMax, tySpawnMax, widthSpawnMax, widthSpawnMax); - graphics.DrawEllipse(Pens.Red, txHomeRange, tyHomeRange, widthHome, widthHome); - graphics.DrawString(flock.Configuration.Name, new Font("Tahoma", 10), Brushes.Red, txSpawnMax, tySpawnMax); + var pen1 = new SKPaint { Color = SKColors.BlueViolet, Style = SKPaintStyle.Stroke }; + var rect1 = new SKRectI(txSpawnMax, tySpawnMax, widthSpawnMax, widthSpawnMax); + canvas.DrawOval(rect1, pen1); + var pen2 = new SKPaint { Color = SKColors.Red, Style = SKPaintStyle.Stroke }; + var rect2 = new SKRectI(txHomeRange, tyHomeRange, widthHome, widthHome); + canvas.DrawOval(rect2, pen2); + var textPaint = new SKPaint { Color = SKColors.Red }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 10); + canvas.DrawText(flock.Configuration.Name, txSpawnMax, tySpawnMax, font, textPaint); } } - private Bitmap CreateMissionTargetsMap() + private SKBitmap CreateMissionTargetsMap() { - return CreateAltitudeBitmap().WithGraphics(DrawMissionTargetsOnGraphics); + return CreateAltitudeBitmap().WithCanvas(DrawMissionTargetsOnGraphics); } - private void DrawMissionTargetsOnGraphics(Graphics graphics) + private void DrawMissionTargetsOnGraphics(SKCanvas canvas) { List targets = _missionDataCache.GetAllMissionTargets.Where(t => t.ValidZoneSet && t.ZoneId == _zone.Id).ToList(); @@ -411,14 +426,18 @@ private void DrawMissionTargetsOnGraphics(Graphics graphics) int tx = missionTarget.targetPosition.intX - 2; int ty = missionTarget.targetPosition.intY - 2; const int width = 4; - graphics.DrawEllipse(Pens.BlueViolet, tx, ty, width, width); - graphics.DrawString(targetNames[missionTarget.id], new Font("Tahoma", 8), Brushes.White, tx, ty); + var pen = new SKPaint{ Color = SKColors.BlueViolet, Style = SKPaintStyle.Stroke }; + var rect = new SKRectI(tx, ty, width, width); + canvas.DrawOval(rect, pen); + var textPaint = new SKPaint { Color = SKColors.White }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 8); + canvas.DrawText(targetNames[missionTarget.id], tx, ty, font, textPaint); } } - private Bitmap CreateDecorBlockingMap() + private SKBitmap CreateDecorBlockingMap() { return CreateAltitudeBitmap().ForEach((bmp, x, y) => { @@ -428,12 +447,12 @@ private Bitmap CreateDecorBlockingMap() return; } - Color color = blockingInfo.Height > 0 ? Color.Green : Color.Orange; + SKColor color = blockingInfo.Height > 0 ? SKColors.Green : SKColors.Orange; bmp.SetPixel(x, y, color); }); } - private Bitmap CreateElectroPlantMap() + private SKBitmap CreateElectroPlantMap() { return CreateAltitudeBitmap().ForEach((bmp, x, y) => { @@ -444,12 +463,12 @@ private Bitmap CreateElectroPlantMap() return; } - int r = (255 / 5 * plantInfo.state).Clamp(0, 255); - Color color = Color.FromArgb(255, r, 128, 0); + byte r = (byte)(255 / 5 * plantInfo.state).Clamp(0, 255); + SKColor color = new(r, 128, 0); if (plantInfo.state == 0) { - color = Color.FromArgb(255, 255, 0, 30); + color = new(255, 0, 30); } bmp.SetPixel(x, y, color); @@ -457,7 +476,7 @@ private Bitmap CreateElectroPlantMap() } - private Bitmap CreatePlantMap(PlantType plantType) + private SKBitmap CreatePlantMap(PlantType plantType) { return CreateAltitudeBitmap().ForEach((bmp, x, y) => { @@ -468,12 +487,12 @@ private Bitmap CreatePlantMap(PlantType plantType) return; } - int r = (255 / 5 * plantInfo.state).Clamp(0, 255); - Color color = Color.FromArgb(255, r, 128, 0); + byte r = (byte)(255 / 5 * plantInfo.state).Clamp(0, 255); + SKColor color = new(r, 128, 0); if (plantInfo.state == 0) { - color = Color.FromArgb(255, 255, 0, 30); + color = new(255, 0, 30); } bmp.SetPixel(x, y, color); @@ -481,7 +500,7 @@ private Bitmap CreatePlantMap(PlantType plantType) } - private Bitmap CreatePlantsMap() + private SKBitmap CreatePlantsMap() { return _zone.CreateBitmap().ForEach((bmp, x, y) => { @@ -497,44 +516,45 @@ private Bitmap CreatePlantsMap() return; } - bmp.SetPixel(x, y, Color.White); + bmp.SetPixel(x, y, SKColors.White); }); } - private Bitmap CreateStructuresMap() + private SKBitmap CreateStructuresMap() { - return _zone.CreateBitmap().WithGraphics(g => + return _zone.CreateBitmap().WithCanvas(c => { foreach (Unit unit in _zone.GetStaticUnits()) { int size = 3; - Pen pen = Pens.White; + var pen = new SKPaint { Color = SKColors.White, Style = SKPaintStyle.Stroke }; if (unit.IsCategory(CategoryFlags.cf_outpost)) { - pen = Pens.LightSeaGreen; + pen.Color = SKColors.LightSeaGreen; size = 150; } else if (unit.IsCategory(CategoryFlags.cf_public_docking_base)) { - pen = Pens.Yellow; + pen.Color = SKColors.Yellow; size = 150; } else if (unit.IsCategory(CategoryFlags.cf_teleport_column)) { - pen = Pens.WhiteSmoke; + pen.Color = SKColors.WhiteSmoke; size = 100; } int x = unit.CurrentPosition.intX - (size / 2); int y = unit.CurrentPosition.intY - (size / 2); - g.DrawEllipse(pen, x, y, size, size); + var rect = new SKRectI(x, y, size, size); + c.DrawOval(rect, pen); } }); } - private Bitmap CreateWallMap() + private SKBitmap CreateWallMap() { return CreateAltitudeBitmap().ForEach((bmp, x, y) => { @@ -544,14 +564,14 @@ private Bitmap CreateWallMap() return; } - int r = (255 / 11 * pInfo.state).Clamp(0, 255); + byte r = (byte)(255 / 11 * pInfo.state).Clamp(0, 255); byte g = pInfo.health; - Color pColor = Color.FromArgb(255, r, g, 0); + SKColor pColor = new(r, g, 0); bmp.SetPixel(x, y, pColor); }); } - private Bitmap CreateWallPossibleMap() + private SKBitmap CreateWallPossibleMap() { Outpost[] outposts = _zone.Units.OfType().ToArray(); Teleport[] teleports = _zone.Units.OfType().ToArray(); @@ -587,11 +607,11 @@ private Bitmap CreateWallPossibleMap() return; } - Color pixel = bmp.GetPixel(x, y); + SKColor pixel = bmp.GetPixel(x, y); - byte r = pixel.R; - byte g = pixel.G; - byte b = pixel.B; + byte r = pixel.Red; + byte g = pixel.Green; + byte b = pixel.Blue; if (allowed) { @@ -605,12 +625,12 @@ private Bitmap CreateWallPossibleMap() b = 0; } - bmp.SetPixel(x, y, Color.FromArgb(255, r, g, b)); + bmp.SetPixel(x, y, new(r, g, b)); }); } - private Bitmap CreateWallPlaces() + private SKBitmap CreateWallPlaces() { Outpost[] outposts = _zone.Units.OfType().ToArray(); Teleport[] teleports = _zone.Units.OfType().ToArray(); @@ -640,12 +660,12 @@ private Bitmap CreateWallPlaces() if (allowed) { - bmp.SetPixel(x, y, Color.FromArgb(255, 255, 0, 0)); + bmp.SetPixel(x, y, new(255, 0, 0)); } }); } - private Bitmap CreateIslandMaskMap() + private SKBitmap CreateIslandMaskMap() { return _zone.CreateBitmap().ForEach((bmp, x, y) => { @@ -655,11 +675,11 @@ private Bitmap CreateIslandMaskMap() return; } - bmp.SetPixel(x, y, Color.White); + bmp.SetPixel(x, y, SKColors.White); }); } - private Func CreateControlFlagMap(TerrainControlFlags flag) + private Func CreateControlFlagMap(TerrainControlFlags flag) { return () => { @@ -671,35 +691,35 @@ private Func CreateControlFlagMap(TerrainControlFlags flag) return; } - bmp.SetPixel(x, y, Color.White); + bmp.SetPixel(x, y, SKColors.White); }); }; } - private Bitmap CreateControlMap() + private SKBitmap CreateControlMap() { return _zone.CreateBitmap().ForEach((bmp, x, y) => { TerrainControlInfo control = _zone.Terrain.Controls.GetValue(x, y); - int c = (int)control.Flags; - bmp.SetPixel(x, y, Color.FromArgb(c, c, c)); + byte c = (byte)control.Flags; + bmp.SetPixel(x, y, new(c, c, c)); }); } - private Bitmap CreateGroundTypeMap() + private SKBitmap CreateGroundTypeMap() { int numGroundTypes = Enum.GetNames(typeof(GroundType)).Length; - Color[] colors = new Color[numGroundTypes]; + SKColor[] colors = new SKColor[numGroundTypes]; Random random = new(numGroundTypes); for (int i = 0; i < colors.Length; i++) { - colors[i] = Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)); + colors[i] = new((byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255)); } return _zone.CreateBitmap().ForEach((bmp, x, y) => { GroundType groundType = _zone.Terrain.Plants.GetValue(x, y).groundType; - Color c = colors[((int)groundType).Clamp(0, numGroundTypes - 1)]; + SKColor c = colors[((int)groundType).Clamp(0, numGroundTypes - 1)]; bmp.SetPixel(x, y, c); }); } @@ -714,9 +734,9 @@ private void CreateMineralBitmaps() } [CanBeNull] - private Bitmap CreateMineralsToNormalizedBitmap(MineralLayer layer) + private SKBitmap CreateMineralsToNormalizedBitmap(MineralLayer layer) { - Bitmap bitmap = _zone.CreatePassableBitmap(_passableColor); + SKBitmap bitmap = _zone.CreatePassableBitmap(_passableColor); foreach (MineralNode node in layer.Nodes) { @@ -729,24 +749,26 @@ private Bitmap CreateMineralsToNormalizedBitmap(MineralLayer layer) double n = (double)node.GetValue(x, y) / maxAmount; if (n > 0.0) { - int c = (int)(n * 255); - bitmap.SetPixel(x, y, Color.FromArgb(c, 0, 0)); + byte c = (byte)(n * 255); + bitmap.SetPixel(x, y, new(c, 0, 0)); } } } } - return bitmap.WithGraphics(g => + return bitmap.WithCanvas(c => { string infoString = $"{layer.Type}"; - g.DrawString(infoString, new Font("Tahoma", 10), Brushes.White, 10, 10); + var paint = new SKPaint { Color = SKColors.White }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 10); + c.DrawText(infoString, 10, 10, font, paint); }); } private void CreateTeleportDecorMaps() { - CreateTeleportDecorMaps(out Bitmap bitmap, out Bitmap circlesBitmap); + CreateTeleportDecorMaps(out SKBitmap bitmap, out SKBitmap circlesBitmap); CreateAndSave("teleportdecor", () => bitmap); CreateAndSave("teleportdecor_circles", () => circlesBitmap); @@ -756,7 +778,7 @@ private void CreateTeleportDecorMaps() /// This function creates the blend map on gamma islands around the teleports /// Finds the farthest decor tile and draws a smooth circle gradient around the teleport /// - private void CreateTeleportDecorMaps(out Bitmap? bitmap, out Bitmap? circlesBitmap) + private void CreateTeleportDecorMaps(out SKBitmap? bitmap, out SKBitmap? circlesBitmap) { bitmap = null; circlesBitmap = null; @@ -768,12 +790,12 @@ private void CreateTeleportDecorMaps(out Bitmap? bitmap, out Bitmap? circlesBitm ITerrain terrain = _zone.Terrain; bitmap = _zone.CreateBitmap(); - Color color = Color.MediumVioletRed; - Font font = new("Tahoma", 8); - Graphics graphics = Graphics.FromImage(bitmap); + SKColor color = SKColors.MediumVioletRed; + SKFont font = new(SKTypeface.FromFamilyName("Tahoma"), 8); + SKCanvas canvas = new(bitmap); circlesBitmap = _zone.CreateBitmap(); - Graphics circlesGraphics = Graphics.FromImage(circlesBitmap); + SKCanvas circlesGraphics = new(circlesBitmap); ushort[] blendData = _zone.Size.CreateArray(); @@ -783,7 +805,7 @@ private void CreateTeleportDecorMaps(out Bitmap? bitmap, out Bitmap? circlesBitm double maximumDistance = 0.0; - Bitmap tmpBmp = bitmap; + SKBitmap tmpBmp = bitmap; area.ForEachXY((x, y) => { if (x < 0 || x >= _zone.Size.Width || y < 0 || y >= _zone.Size.Height) @@ -806,14 +828,17 @@ private void CreateTeleportDecorMaps(out Bitmap? bitmap, out Bitmap? circlesBitm tmpBmp.SetPixel(x, y, color); }); - graphics.DrawString(maximumDistance.ToString(CultureInfo.InvariantCulture), font, Brushes.White, (float)td.CurrentPosition.X, (float)td.CurrentPosition.Y); + var textPaint = new SKPaint { Color = SKColors.White }; + canvas.DrawText(maximumDistance.ToString(CultureInfo.InvariantCulture), (float)td.CurrentPosition.X, (float)td.CurrentPosition.Y, font, textPaint); if (maximumDistance <= 0) { continue; } - circlesGraphics.FillEllipse(Brushes.White, (float)(td.CurrentPosition.intX - maximumDistance), (float)(td.CurrentPosition.intY - maximumDistance), (float)(maximumDistance * 2), (float)(maximumDistance * 2)); + var paint = new SKPaint { Color = SKColors.White, Style = SKPaintStyle.Fill }; + var rect = SKRect.Create((float)(td.CurrentPosition.intX - maximumDistance), (float)(td.CurrentPosition.intY - maximumDistance), (float)(maximumDistance * 2), (float)(maximumDistance * 2)); + circlesGraphics.DrawOval(rect, paint); Area tpArea = Area.FromRadius(td.CurrentPosition, (int)maximumDistance + 200); tpArea.ForEachXY((x, y) => @@ -850,39 +875,39 @@ private void CreateMissionMapByLevels() - private Bitmap DrawMissionByLevels() + private SKBitmap DrawMissionByLevels() { - Bitmap b = CreateAltitudeBitmap(); + SKBitmap b = CreateAltitudeBitmap(); DrawPixels(b); - b.WithGraphics(DrawLayers); + b.WithCanvas(DrawLayers); return b; } - private void DrawLayers(Graphics g) + private void DrawLayers(SKCanvas g) { DrawStringTopLeft(g, "valami cucc rajta"); //... tobbi graphics piszkalo } - private void DrawPixels(Bitmap bitmap) + private void DrawPixels(SKBitmap bitmap) { DrawPassableInGreen(bitmap); //... tobbi bitmap piszkalo } - private void DrawPassableInGreen(Bitmap bmp) + private void DrawPassableInGreen(SKBitmap bmp) { bmp.ForEach((b, x, y) => { - Color blockedColor = Color.FromArgb(255, 0, 0, 0); - Color passableColor = Color.FromArgb(255, 60, 60, 60); + SKColor blockedColor = new(0, 0, 0); + SKColor passableColor = new(60, 60, 60); if (_zone.Terrain.IsPassable(new Position(x, y))) { @@ -896,9 +921,11 @@ private void DrawPassableInGreen(Bitmap bmp) } - private void DrawStringTopLeft(Graphics graphics, string text) + private void DrawStringTopLeft(SKCanvas canvas, string text) { - graphics.DrawString(text, new Font("Tahoma", 20), Brushes.Chocolate, new PointF(50, 100)); + var paint = new SKPaint { Color = SKColors.Chocolate }; + var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 20); + canvas.DrawText(text, 50, 100, font, paint); } private void SendDrawFunctionFinished(IRequest request) diff --git a/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs b/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs index 6e5ddec..430cd89 100644 --- a/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs +++ b/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs @@ -1,8 +1,8 @@ -using System.Drawing; -using Perpetuum.Host.Requests; +using Perpetuum.Host.Requests; using Perpetuum.IO; using Perpetuum.Zones; using Perpetuum.Zones.Terrains; +using SkiaSharp; namespace Perpetuum.RequestHandlers.Zone { @@ -22,12 +22,12 @@ public void HandleRequest(IZoneRequest request) var flagValue = request.Data.GetOrDefault(k.flags); var controlFlag = EnumHelper.GetEnum(flagValue); var path = _fileSystem.CreatePath("bitmaps", zone.CreateTerrainDataFilename(fileName, "png")); - var img = Image.FromFile(path); - using (Bitmap bmp = new Bitmap(img)) + var img = SKImage.FromEncodedData(path); + using (SKBitmap bmp = SKBitmap.FromImage(img)) { zone.Terrain.Controls.UpdateAll((x, y, c) => { - if (bmp.GetPixel(x, y).A == 0) + if (bmp.GetPixel(x, y).GetLuminance() == 0) { return c; } diff --git a/src/Perpetuum.Server/Program.cs b/src/Perpetuum.Server/Program.cs index 84fb80a..c24f486 100644 --- a/src/Perpetuum.Server/Program.cs +++ b/src/Perpetuum.Server/Program.cs @@ -37,7 +37,8 @@ static int Main(string[] args) return 3; } - bootstrapper.Init(gameRoot.Value); + // TODO: fix a way to take optional argument to be able to configure the DistributedTransactions from here + bootstrapper.Init(gameRoot.Value, true); if (bootstrapper.TryInitUpnp(out bool upnpSuccess)) { diff --git a/src/Perpetuum/Area.cs b/src/Perpetuum/Area.cs index f1ebd63..be939d4 100644 --- a/src/Perpetuum/Area.cs +++ b/src/Perpetuum/Area.cs @@ -1,7 +1,5 @@ using Perpetuum.Zones; -using System; -using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace Perpetuum { @@ -50,7 +48,7 @@ public static Area FromRadius(Position position, int radius) return FromRadius(position.intX, position.intY, radius); } - public static Area FromRadius(Point position, int radius) + public static Area FromRadius(SKPointI position, int radius) { return FromRadius(position.X, position.Y, radius); } @@ -95,7 +93,7 @@ public Position CenterPrecise get { return new Position((_x1 + _x2) / 2.0, (_y1 + _y2) / 2.0); } } - public Point Center + public SKPointI Center { get { return new Position((Width >> 1) + _x1, (Height >> 1) + _y1); } } @@ -116,7 +114,7 @@ public int GetOffset(int x, int y) return x + y * Width; } - public bool Contains(Point target) + public bool Contains(SKPointI target) { return Contains(target.X, target.Y); } @@ -152,7 +150,7 @@ public override string ToString() return $"X1 = {X1} Y1 = {Y1} X2 = {X2} Y2 = {Y2} Width = {Width} Height = {Height}"; } - public Area Clamp(Size size) + public Area Clamp(SKSizeI size) { return Clamp(size.Width, size.Height); } @@ -207,11 +205,11 @@ private IEnumerable Slice(int w,int h) } while (y1 < _y2); } - public Point GetRandomPosition() + public SKPointI GetRandomPosition() { var x = FastRandom.NextInt(_x1,_x2); var y = FastRandom.NextInt(_y1,_y2); - return new Point(x, y); + return new SKPointI(x, y); } public Area AddBorder(int border) @@ -230,7 +228,7 @@ public IEnumerable GetPositions() } } - public double Distance(Point p) + public double Distance(SKPointI p) { return Distance(p.X,p.Y); } @@ -240,7 +238,7 @@ public double Distance(int x, int y) return Math.Sqrt(SqrDistance(x, y)); } - public double SqrDistance(Point p) + public double SqrDistance(SKPointI p) { return SqrDistance(p.X,p.Y); } diff --git a/src/Perpetuum/BinaryStream.cs b/src/Perpetuum/BinaryStream.cs index e4dc719..4c0b633 100644 --- a/src/Perpetuum/BinaryStream.cs +++ b/src/Perpetuum/BinaryStream.cs @@ -1,7 +1,7 @@ using Perpetuum.Zones; using System.Diagnostics; -using System.Drawing; using System.Text; +using SkiaSharp; namespace Perpetuum { @@ -98,11 +98,11 @@ public void AppendObject(object o) return; } - if (o is Color color) + if (o is SKColor color) { - AppendByte(color.R); - AppendByte(color.G); - AppendByte(color.B); + AppendByte(color.Red); + AppendByte(color.Green); + AppendByte(color.Blue); return; } @@ -168,7 +168,7 @@ public void AppendStream(BinaryStream stream) AppendByteArray(stream.ToArray()); } - public void AppendPoint(Point p) + public void AppendPoint(SKPointI p) { AppendInt(p.X); AppendInt(p.Y); diff --git a/src/Perpetuum/BitmapExtensions.cs b/src/Perpetuum/BitmapExtensions.cs index 7a1ae46..6b6392f 100644 --- a/src/Perpetuum/BitmapExtensions.cs +++ b/src/Perpetuum/BitmapExtensions.cs @@ -1,20 +1,21 @@ -using System.Drawing; +using SkiaSharp; namespace Perpetuum { public static class BitmapExtensions { [CanBeNull] - public static Bitmap? WithGraphics(this Bitmap bitmap, Action action) + public static SKBitmap? WithCanvas(this SKBitmap bitmap, Action action) { if (bitmap == null) { return null; } - using (Graphics g = Graphics.FromImage(bitmap)) + using (var surface = SKSurface.Create(new SKImageInfo(bitmap.Width, bitmap.Height))) { - action(g); + var canvas = surface.Canvas; + action(canvas); } return bitmap; @@ -24,7 +25,7 @@ public static class BitmapExtensions /// Runs an action on every pixel of a bitmap /// [CanBeNull] - public static Bitmap? ForEach(this Bitmap bitmap, Action action) + public static SKBitmap? ForEach(this SKBitmap bitmap, Action action) { if (bitmap == null) { diff --git a/src/Perpetuum/Collections/Spatial/Grid.NonGeneric.cs b/src/Perpetuum/Collections/Spatial/Grid.NonGeneric.cs index 6d34126..62e4939 100644 --- a/src/Perpetuum/Collections/Spatial/Grid.NonGeneric.cs +++ b/src/Perpetuum/Collections/Spatial/Grid.NonGeneric.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Collections.Spatial { @@ -20,9 +19,9 @@ public class Grid {GridDistricts.RightLower,new CellCoord(1, 1)} }; - public static Size CalculateGridSize(Size size) + public static SKSizeI CalculateGridSize(SKSizeI size) { - return new Size(size.Width / TilesPerGrid, size.Height / TilesPerGrid); + return new SKSizeI(size.Width / TilesPerGrid, size.Height / TilesPerGrid); } } } \ No newline at end of file diff --git a/src/Perpetuum/Collections/Spatial/Grid.cs b/src/Perpetuum/Collections/Spatial/Grid.cs index 51838d9..b2b0149 100644 --- a/src/Perpetuum/Collections/Spatial/Grid.cs +++ b/src/Perpetuum/Collections/Spatial/Grid.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Collections.Spatial { @@ -48,8 +46,8 @@ public Grid(int width, int height, int cellsX, int cellsY, Func cel neighbours[cell] = new List(); - Point p = new Point(x, y); - foreach (Point np in p.GetNeighbours()) + SKPointI p = new SKPointI(x, y); + foreach (SKPointI np in p.GetNeighbours()) { if (np.X < 0 || np.X >= numCellsX || np.Y < 0 || np.Y >= numCellsY) { @@ -68,7 +66,7 @@ private int GetCellCoordIndex(int x, int y) } [CanBeNull] - public TCell GetCell(Point p) + public TCell GetCell(SKPointI p) { return GetCell(p.X, p.Y); } diff --git a/src/Perpetuum/Collections/Spatial/QuadTree.cs b/src/Perpetuum/Collections/Spatial/QuadTree.cs index 5c4aa41..7db1eb2 100644 --- a/src/Perpetuum/Collections/Spatial/QuadTree.cs +++ b/src/Perpetuum/Collections/Spatial/QuadTree.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Collections.Spatial { @@ -12,7 +11,7 @@ public QuadTree(Area area) Root = new QuadTreeNode(area); } - public QuadTreeItem Add(Point position, T value) + public QuadTreeItem Add(SKPointI position, T value) { return Add(position.X, position.Y, value); } diff --git a/src/Perpetuum/ColorExtensions.cs b/src/Perpetuum/ColorExtensions.cs new file mode 100644 index 0000000..e5aeddf --- /dev/null +++ b/src/Perpetuum/ColorExtensions.cs @@ -0,0 +1,17 @@ +using SkiaSharp; + +namespace Perpetuum +{ + public static class ColorExtensions + { + /// + /// Get the luminance/brightness of this SKColor. + /// + /// The color/pixel to evaluate + /// Luminance between 0.0 and 1.0 + public static float GetLuminance(this SKColor color) + { + return (0.299f * color.Red + 0.587f * color.Green + 0.114f * color.Blue) / 255f; + } + } +} \ No newline at end of file diff --git a/src/Perpetuum/Commands.cs b/src/Perpetuum/Commands.cs index f7e02de..3a2229f 100644 --- a/src/Perpetuum/Commands.cs +++ b/src/Perpetuum/Commands.cs @@ -1,5 +1,5 @@ -using System.Drawing; using System.Reflection; +using SkiaSharp; namespace Perpetuum { @@ -4825,7 +4825,7 @@ public static Command GetCommandByText(string commandText) Arguments = { new Argument(k.robotEID), - new Argument(k.tint), + new Argument(k.tint), } }; diff --git a/src/Perpetuum/EnumerableExtensions.cs b/src/Perpetuum/EnumerableExtensions.cs index f0d9f83..a6271ed 100644 --- a/src/Perpetuum/EnumerableExtensions.cs +++ b/src/Perpetuum/EnumerableExtensions.cs @@ -1,10 +1,7 @@ -using System; using System.Collections; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; -using System.Linq; namespace Perpetuum { diff --git a/src/Perpetuum/GenXY/GenxyConverter.cs b/src/Perpetuum/GenXY/GenxyConverter.cs index a34a570..7008496 100644 --- a/src/Perpetuum/GenXY/GenxyConverter.cs +++ b/src/Perpetuum/GenXY/GenxyConverter.cs @@ -1,8 +1,8 @@ using Perpetuum.Zones; using System.Collections; using System.Diagnostics; -using System.Drawing; using System.Dynamic; +using SkiaSharp; namespace Perpetuum.GenXY { @@ -33,9 +33,9 @@ static GenxyConverter() RegisterConverter(ConvertDecimalArray); RegisterConverter(ConvertFloat); RegisterConverter(CreateDoubleConverter); - RegisterConverter(ConvertColor); + RegisterConverter(ConvertColor); RegisterConverter(ConvertDateTime); - RegisterConverter(ConvertPoint); + RegisterConverter(ConvertPoint); RegisterConverter(ConvertPosition); RegisterConverter(ConvertPositionArray); RegisterConverter(ConvertArea); @@ -127,16 +127,16 @@ private static void CreateDoubleConverter(GenxyWriter writer, double value) ConvertFloat(writer, (float)value); } - private static void ConvertColor(GenxyWriter writer, Color color) + private static void ConvertColor(GenxyWriter writer, SKColor color) { writer.WriteToken(GenxyToken.Color); - writer.WriteHexInteger(color.R); + writer.WriteHexInteger(color.Red); writer.WriteChar('.'); - writer.WriteHexInteger(color.G); + writer.WriteHexInteger(color.Green); writer.WriteChar('.'); - writer.WriteHexInteger(color.B); + writer.WriteHexInteger(color.Blue); writer.WriteChar('.'); - writer.WriteHexInteger(color.A); + writer.WriteHexInteger(color.Alpha); } private static void ConvertDateTime(GenxyWriter writer, DateTime date) @@ -155,7 +155,7 @@ private static void ConvertDateTime(GenxyWriter writer, DateTime date) writer.WriteInteger(date.Second); } - private static void ConvertPoint(GenxyWriter writer, Point point) + private static void ConvertPoint(GenxyWriter writer, SKPointI point) { writer.WriteToken(GenxyToken.Point); writer.WriteHexInteger(point.X); diff --git a/src/Perpetuum/GenXY/GenxyReader.cs b/src/Perpetuum/GenXY/GenxyReader.cs index f22f85d..dcab0b9 100644 --- a/src/Perpetuum/GenXY/GenxyReader.cs +++ b/src/Perpetuum/GenXY/GenxyReader.cs @@ -1,8 +1,8 @@ using Perpetuum.Threading; using Perpetuum.Zones; -using System.Drawing; using System.Globalization; using System.Text; +using SkiaSharp; namespace Perpetuum.GenXY { @@ -245,10 +245,10 @@ private DateTime ReadDate() return new DateTime(n[0], n[1], n[2], n[3], n[4], n[5]); } - private Color ReadColor() + private SKColor ReadColor() { int[] n = ReadValueAsArray(ParseInt, '.'); - return Color.FromArgb(n[3], n[0], n[1], n[2]); + return new SKColor((byte)n[0], (byte)n[1], (byte)n[2], (byte)n[3]); } private Area ReadArea() @@ -262,10 +262,10 @@ private Area[] ReadAreaArray() return ReadValueAsArray(ParseArea); } - private Point ReadPoint() + private SKPointI ReadPoint() { int[] n = ReadValueAsArray(ParseInt, '.'); - return new Point(n[0], n[1]); + return new SKPointI(n[0], n[1]); } private Position ReadPosition() diff --git a/src/Perpetuum/Items/Paint.cs b/src/Perpetuum/Items/Paint.cs index 9bfa9dc..34e3a1f 100644 --- a/src/Perpetuum/Items/Paint.cs +++ b/src/Perpetuum/Items/Paint.cs @@ -1,11 +1,4 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using Perpetuum.Accounting.Characters; -using Perpetuum.Common.Loggers.Transaction; -using Perpetuum.Containers; -using Perpetuum.Data; -using Perpetuum.EntityFramework; +using Perpetuum.Accounting.Characters; using Perpetuum.Robots; namespace Perpetuum.Items diff --git a/src/Perpetuum/Modules/DrillerModule.cs b/src/Perpetuum/Modules/DrillerModule.cs index c0216cb..a34a806 100644 --- a/src/Perpetuum/Modules/DrillerModule.cs +++ b/src/Perpetuum/Modules/DrillerModule.cs @@ -14,8 +14,8 @@ using Perpetuum.Zones.Terrains.Materials; using Perpetuum.Zones.Terrains.Materials.Minerals; using System.Diagnostics; -using System.Drawing; using System.Transactions; +using SkiaSharp; namespace Perpetuum.Modules { @@ -68,7 +68,7 @@ public override void UpdateProperty(AggregateField field) base.UpdateProperty(field); } - public List Extract(MineralLayer layer, Point location, uint amount) + public List Extract(MineralLayer layer, SKPointI location, uint amount) { if (!layer.HasMineral(location)) { diff --git a/src/Perpetuum/Modules/LargeHarvesterModule.cs b/src/Perpetuum/Modules/LargeHarvesterModule.cs index b2fa8fd..b861733 100644 --- a/src/Perpetuum/Modules/LargeHarvesterModule.cs +++ b/src/Perpetuum/Modules/LargeHarvesterModule.cs @@ -60,7 +60,7 @@ public override void DoHarvesting(IZone zone) Debug.Assert(ParentRobot != null, "ParentRobot != null"); - Robots.RobotInventory container = ParentRobot.GetContainer(); + Robots.RobotInventory container = ParentRobot.GetContainer(); Debug.Assert(container != null, "container != null"); container.EnlistTransaction(); Player player = ParentRobot is RemoteControlledCreature remoteControlledCreature && diff --git a/src/Perpetuum/PathFinders/AStarFinder.cs b/src/Perpetuum/PathFinders/AStarFinder.cs index 729e078..a2516f1 100644 --- a/src/Perpetuum/PathFinders/AStarFinder.cs +++ b/src/Perpetuum/PathFinders/AStarFinder.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Threading; -using Perpetuum.Collections; -using Perpetuum.ExportedTypes; -using Perpetuum.Zones; +using Perpetuum.Collections; +using SkiaSharp; namespace Perpetuum.PathFinders { @@ -27,7 +22,7 @@ public AStarLimited(Heuristic heuristic, PathFinderNodePassableHandler passableH /// Start point /// End point /// True if path is found and shorter than MAX_DEPTH - public bool HasPath(Point start, Point end) + public bool HasPath(SKPointI start, SKPointI end) { if (!_passableHandler(end.X, end.Y)) return false; @@ -92,7 +87,7 @@ public AStarFinder(Heuristic heuristic,PathFinderNodePassableHandler passableHan public int Weight { get; set; } - public override Point[] FindPath(Point start, Point end,CancellationToken cancellationToken) + public override SKPointI[] FindPath(SKPointI start, SKPointI end, CancellationToken cancellationToken) { if (!_passableHandler(end.X, end.Y)) return null; @@ -138,9 +133,9 @@ public override Point[] FindPath(Point start, Point end,CancellationToken cancel return null; } - protected Point[] Backtrace(Node node) + protected SKPointI[] Backtrace(Node node) { - var stack = new Stack(); + var stack = new Stack(); while (node != null) { diff --git a/src/Perpetuum/PathFinders/PathFinder.cs b/src/Perpetuum/PathFinders/PathFinder.cs index 888c000..34d1687 100644 --- a/src/Perpetuum/PathFinders/PathFinder.cs +++ b/src/Perpetuum/PathFinders/PathFinder.cs @@ -1,17 +1,15 @@ using System.Diagnostics; -using System.Drawing; -using System.Threading; -using System.Threading.Tasks; +using SkiaSharp; namespace Perpetuum.PathFinders { public class PathFinderNode { - public Point Location { get; private set; } + public SKPointI Location { get; private set; } public PathFinderNode(int x,int y) { - Location = new Point(x,y); + Location = new SKPointI(x,y); } public override string ToString() @@ -29,7 +27,7 @@ public abstract class PathFinder { public const float SQRT2 = 1.41f; - protected static readonly Point[] EmptyPath = new Point[0]; + protected static readonly SKPointI[] EmptyPath = []; public delegate bool PathFinderNodePassableHandler(int x, int y); @@ -40,18 +38,18 @@ public abstract class PathFinder #endif [CanBeNull] - public Point[] FindPath(Point start, Point end) + public SKPointI[] FindPath(SKPointI start, SKPointI end) { return FindPath(start, end, CancellationToken.None); } - public Task FindPathAsync(Point start, Point end) + public Task FindPathAsync(SKPointI start, SKPointI end) { return Task.Run(() => FindPath(start, end)); } [CanBeNull] - public abstract Point[] FindPath(Point start, Point end, CancellationToken cancellationToken); + public abstract SKPointI[] FindPath(SKPointI start, SKPointI end, CancellationToken cancellationToken); [Conditional("DEBUG")] public void RegisterDebugHandler(PathFinderDebugHandler handler) diff --git a/src/Perpetuum/Perpetuum.csproj b/src/Perpetuum/Perpetuum.csproj index 1f41f0f..4c69af8 100644 --- a/src/Perpetuum/Perpetuum.csproj +++ b/src/Perpetuum/Perpetuum.csproj @@ -23,7 +23,8 @@ - + + diff --git a/src/Perpetuum/Players/PlayerMoveChecker.cs b/src/Perpetuum/Players/PlayerMoveChecker.cs index cbe8a64..c6998db 100644 --- a/src/Perpetuum/Players/PlayerMoveChecker.cs +++ b/src/Perpetuum/Players/PlayerMoveChecker.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Concurrent; -using System.Threading; -using System.Threading.Tasks; +using System.Collections.Concurrent; using Perpetuum.Log; using Perpetuum.PathFinders; using Perpetuum.Threading; diff --git a/src/Perpetuum/PointExtensions.cs b/src/Perpetuum/PointExtensions.cs index 13e12bd..48889b0 100644 --- a/src/Perpetuum/PointExtensions.cs +++ b/src/Perpetuum/PointExtensions.cs @@ -1,6 +1,6 @@ using Perpetuum.Zones; -using System.Drawing; using System.Numerics; +using SkiaSharp; namespace Perpetuum { @@ -9,35 +9,35 @@ public static class PointExtensions private static readonly int[,] _neighbours = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { -1, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } }; private static readonly int[,] _nonDiagonalNeighbours = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; - public static Position ToPosition(this Point p) + public static Position ToPosition(this SKPointI p) { return new Position(p.X + 0.5, p.Y + 0.5); } - public static Position ToPosition(this PointF p) + public static Position ToPosition(this SKPoint p) { return new Position(p.X, p.Y); } - public static IEnumerable GetNonDiagonalNeighbours(this Point point) + public static IEnumerable GetNonDiagonalNeighbours(this SKPointI point) { for (int i = 0; i < 4; i++) { int nx = point.X + _nonDiagonalNeighbours[i, 0]; int ny = point.Y + _nonDiagonalNeighbours[i, 1]; - yield return new Point(nx, ny); + yield return new SKPointI(nx, ny); } } - public static IEnumerable GetNeighbours(this Point point) + public static IEnumerable GetNeighbours(this SKPointI point) { for (int i = 0; i < 8; i++) { int nx = point.X + _neighbours[i, 0]; int ny = point.Y + _neighbours[i, 1]; - yield return new Point(nx, ny); + yield return new SKPointI(nx, ny); } } @@ -53,7 +53,7 @@ public static IEnumerable GetNeighbours(this Vector2 v) } - public static IEnumerable GetNeighbours(this Point point, int size) + public static IEnumerable GetNeighbours(this SKPointI point, int size) { for (int y = -size; y <= size; y++) { @@ -62,7 +62,7 @@ public static IEnumerable GetNeighbours(this Point point, int size) int nx = point.X + x; int ny = point.Y + y; - yield return new Point(nx, ny); + yield return new SKPointI(nx, ny); } } } @@ -81,12 +81,12 @@ public static IEnumerable GetNeighbours(this Vector2 v, int size) } } - public static Point GetNearestPoint(this Point point, IEnumerable points) + public static SKPointI GetNearestPoint(this SKPointI point, IEnumerable points) { - Point nearestPoint = Point.Empty; + SKPointI nearestPoint = SKPointI.Empty; int nearestDistSq = int.MaxValue; - foreach (Point p in points) + foreach (SKPointI p in points) { int distSqr = SqrDistance(point, p); if (distSqr >= nearestDistSq) @@ -101,22 +101,22 @@ public static Point GetNearestPoint(this Point point, IEnumerable points) return nearestPoint; } - public static bool IsInRange(this Point p1, Point p2, double range) + public static bool IsInRange(this SKPointI p1, SKPointI p2, double range) { return p1.SqrDistance(p2) <= range * range; } - public static double Distance(this Point p1, Point p2) + public static double Distance(this SKPointI p1, SKPointI p2) { return Math.Sqrt(SqrDistance(p1, p2)); } - public static int SqrDistance(this Point p1, Point p2) + public static int SqrDistance(this SKPointI p1, SKPointI p2) { return SqrDistance(p1, p2.X, p2.Y); } - public static int SqrDistance(this Point p1, int x, int y) + public static int SqrDistance(this SKPointI p1, int x, int y) { int dx = p1.X - x; int dy = p1.Y - y; @@ -124,7 +124,7 @@ public static int SqrDistance(this Point p1, int x, int y) } [UsedImplicitly] - public static double DirectionTo(this Point from, Point to) + public static double DirectionTo(this SKPointI from, SKPointI to) { int dx = to.X - from.X; int dy = to.Y - from.Y; @@ -157,29 +157,29 @@ public static double DirectionTo(this Point from, Point to) private const double PI2 = Math.PI * 2; - public static Point OffsetInDirection(this Point p, double direction, double distance) + public static SKPointI OffsetInDirection(this SKPointI p, double direction, double distance) { double angleRadians = direction * PI2; double deltaX = Math.Sin(angleRadians) * distance; double deltaY = Math.Cos(angleRadians) * distance; - return new Point((int)(p.X + deltaX), (int)(p.Y - deltaY)); + return new SKPointI((int)(p.X + deltaX), (int)(p.Y - deltaY)); } - public static IEnumerable FloodFill(this Point p, Func? validator = null) + public static IEnumerable FloodFill(this SKPointI p, Func? validator = null) { - Queue q = new(); + Queue q = new(); q.Enqueue(p); - HashSet closed = new() + HashSet closed = new() { p }; - while (q.TryDequeue(out Point current)) + while (q.TryDequeue(out SKPointI current)) { yield return current; - foreach (Point np in current.GetNeighbours()) + foreach (SKPointI np in current.GetNeighbours()) { if (closed.Contains(np)) { @@ -198,7 +198,7 @@ public static IEnumerable FloodFill(this Point p, Func? vali } } - public static Vector2 ToVector2(this Point p) + public static Vector2 ToVector2(this SKPointI p) { return new Vector2(p.X, p.Y); } diff --git a/src/Perpetuum/Robots/Robot.Properties.cs b/src/Perpetuum/Robots/Robot.Properties.cs index 8a2d491..9410f93 100644 --- a/src/Perpetuum/Robots/Robot.Properties.cs +++ b/src/Perpetuum/Robots/Robot.Properties.cs @@ -2,14 +2,14 @@ using Perpetuum.Items; using Perpetuum.Modules; using Perpetuum.Units; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Robots { public partial class Robot { private UnitOptionalProperty decay; - private UnitOptionalProperty tint; + private UnitOptionalProperty tint; private ItemProperty powerGridMax; private ItemProperty powerGrid; @@ -30,7 +30,7 @@ private void InitProperties() }; OptionalProperties.Add(decay); - tint = new UnitOptionalProperty(this, UnitDataType.Tint, k.tint, () => ED.Config.Tint); + tint = new UnitOptionalProperty(this, UnitDataType.Tint, k.tint, () => ED.Config.Tint); OptionalProperties.Add(tint); powerGridMax = new UnitProperty(this, AggregateField.powergrid_max, AggregateField.powergrid_max_modifier); @@ -85,7 +85,7 @@ public int Decay set => decay.Value = value & 255; } - public Color Tint + public SKColor Tint { get => tint.Value; set => tint.Value = value; @@ -209,7 +209,7 @@ protected override double CalculateValue() protected virtual double CamouflageBonus() { // Average value of color components. - double average = (Tint.R + Tint.G + Tint.B) / 3.0; + double average = (Tint.Red + Tint.Green + Tint.Blue) / 3.0; if (Zone == null) { return 0; @@ -218,11 +218,11 @@ protected virtual double CamouflageBonus() var oneColor = Zone.Configuration.RaceId switch { // Pelistal - 1 => Tint.G, + 1 => Tint.Green, // Nuimqol - 2 => Tint.B, + 2 => Tint.Blue, // Thelodica - 3 => Tint.R, + 3 => Tint.Red, // Default for 0.00rF . _ => average, }; diff --git a/src/Perpetuum/Services/MissionEngine/MissionSpotObjects.cs b/src/Perpetuum/Services/MissionEngine/MissionSpotObjects.cs index 735dcc4..2757edf 100644 --- a/src/Perpetuum/Services/MissionEngine/MissionSpotObjects.cs +++ b/src/Perpetuum/Services/MissionEngine/MissionSpotObjects.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Data; -using System.Drawing; -using System.Linq; +using System.Data; using Perpetuum.Data; using Perpetuum.ExportedTypes; using Perpetuum.Services.MissionEngine.MissionDataCacheObjects; @@ -121,7 +118,7 @@ public MissionSpotStat CountSelectableSpots(List allSpotsOnZone) private int CountSelectableByType(MissionSpotType missionSpotType, List spots) { return spots.Count(s => s.type == missionSpotType && - position.ToPoint().ToPosition().TotalDistance2D((Point) s.position.ToPoint()) > 0.5 && + position.ToPoint().ToPosition().TotalDistance2D(s.position.ToPoint()) > 0.5 && position.IsInRangeOf2D(s.position, s.findRadius) && _missionDataCache.IsTargetSelectionValid(Zone, position, s.position)); } diff --git a/src/Perpetuum/Services/MissionEngine/MissionTargets/ZoneMissionTargetObjects.cs b/src/Perpetuum/Services/MissionEngine/MissionTargets/ZoneMissionTargetObjects.cs index 87e4921..065c133 100644 --- a/src/Perpetuum/Services/MissionEngine/MissionTargets/ZoneMissionTargetObjects.cs +++ b/src/Perpetuum/Services/MissionEngine/MissionTargets/ZoneMissionTargetObjects.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Threading.Tasks; -using Perpetuum.EntityFramework; +using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; using Perpetuum.Items; using Perpetuum.Log; @@ -16,17 +11,18 @@ using Perpetuum.Zones.NpcSystem.Flocks; using Perpetuum.Zones.NpcSystem.Presences; using Perpetuum.Zones.Scanning; +using SkiaSharp; namespace Perpetuum.Services.MissionEngine.MissionTargets { public class LootMissionEventInfo : MissionEventInfo { public Item LootedItem { get; private set; } - public Point LootedPosition { get; private set; } + public SKPointI LootedPosition { get; private set; } public Guid MissionGuid { get; private set; } public int DisplayOrder { get; private set; } - public LootMissionEventInfo(Player player, Item lootedItem, Point lootedPosition, Guid missionGuid, int displayOrder) : base(player) + public LootMissionEventInfo(Player player, Item lootedItem, SKPointI lootedPosition, Guid missionGuid, int displayOrder) : base(player) { LootedItem = lootedItem; LootedPosition = lootedPosition; @@ -108,9 +104,9 @@ protected override Dictionary ToDictionary() public class ReachPositionEventInfo : MissionEventInfo { - public Point ReachedPoint { get; private set; } + public SKPointI ReachedPoint { get; private set; } - public ReachPositionEventInfo(Player player, Point reachedPoint) : base(player) + public ReachPositionEventInfo(Player player, SKPointI reachedPoint) : base(player) { ReachedPoint = reachedPoint; } @@ -154,9 +150,9 @@ protected override void OnHandleMissionEvent(ReachPositionEventInfo e) public class PopNpcEventInfo : MissionEventInfo { - public Point PoppedAtPoint { get; private set; } + public SKPointI PoppedAtPoint { get; private set; } - public PopNpcEventInfo(Player player, Point poppedAtpoint) : base(player) + public PopNpcEventInfo(Player player, SKPointI poppedAtpoint) : base(player) { PoppedAtPoint = poppedAtpoint; } @@ -248,9 +244,9 @@ protected override void OnTargetComplete() public class LockUnitEventInfo : MissionEventInfo { public Npc LockedNpc { get; private set; } - public Point LockedPosition { get; private set; } + public SKPointI LockedPosition { get; private set; } - public LockUnitEventInfo(Player player, Npc lockedUnit, Point lockedPosition) : base(player) + public LockUnitEventInfo(Player player, Npc lockedUnit, SKPointI lockedPosition) : base(player) { LockedNpc = lockedUnit; LockedPosition = lockedPosition; @@ -333,10 +329,10 @@ protected override Dictionary ToDictionary() public class KillEventInfo : MissionEventInfo { - public Point KillPoint { get; private set; } + public SKPointI KillPoint { get; private set; } public Npc KilledNpc { get; private set; } - public KillEventInfo(Player player, Npc killedNpc, Point killPoint) : base(player) + public KillEventInfo(Player player, Npc killedNpc, SKPointI killPoint) : base(player) { KillPoint = killPoint; KilledNpc = killedNpc; @@ -426,9 +422,9 @@ public class ScanMaterialEventInfo : MissionEventInfo { public int ScannedDefinition { get; private set; } public MaterialProbeType ScanProbeType { get; private set; } - public Point ScanPoint { get; private set; } + public SKPointI ScanPoint { get; private set; } - public ScanMaterialEventInfo(Player player, int scannedDefinition, MaterialProbeType probeType, Point scanPoint) : base(player) + public ScanMaterialEventInfo(Player player, int scannedDefinition, MaterialProbeType probeType, SKPointI scanPoint) : base(player) { ScannedDefinition = scannedDefinition; ScanProbeType = probeType; @@ -490,9 +486,9 @@ protected override void OnTargetComplete() public class ScanUnitEventInfo : MissionEventInfo { public Npc ScannedNpc { get; private set; } - public Point ScannedPoint { get; private set; } + public SKPointI ScannedPoint { get; private set; } - public ScanUnitEventInfo(Player player, Npc scannedNpc, Point scannedPoint) : base(player) + public ScanUnitEventInfo(Player player, Npc scannedNpc, SKPointI scannedPoint) : base(player) { ScannedNpc = scannedNpc; ScannedPoint = scannedPoint; @@ -566,9 +562,9 @@ protected override Dictionary ToDictionary() public class ScanContainerEventInfo : MissionEventInfo { public Npc ScannedNpc { get; private set; } - public Point ScanPoint { get; private set; } + public SKPointI ScanPoint { get; private set; } - public ScanContainerEventInfo(Player player, Npc scannedNpc, Point scanPoint) : base(player) + public ScanContainerEventInfo(Player player, Npc scannedNpc, SKPointI scanPoint) : base(player) { ScannedNpc = scannedNpc; ScanPoint = scanPoint; @@ -643,9 +639,9 @@ public class HarvestPlantEventInfo : MissionEventInfo { public int HarvestedDefinition { get;private set; } public int HarvestedQuantity { get; private set; } - public Point HarvestedPoint { get; private set; } + public SKPointI HarvestedPoint { get; private set; } - public HarvestPlantEventInfo(Player player, int harvestedDefinition, int harvestedQuantity, Point harvestedPoint):base(player) + public HarvestPlantEventInfo(Player player, int harvestedDefinition, int harvestedQuantity, SKPointI harvestedPoint):base(player) { HarvestedDefinition = harvestedDefinition; HarvestedQuantity = harvestedQuantity; @@ -727,9 +723,9 @@ public class DrillMineralEventInfo : MissionEventInfo { public int DrilledDefinition { get; private set; } public int DrilledQuantity { get; private set; } - public Point DrillPoint { get; private set; } + public SKPointI DrillPoint { get; private set; } - public DrillMineralEventInfo(Player player, int drilledDefinition, int drilledQuantity, Point drillPoint) : base(player) + public DrillMineralEventInfo(Player player, int drilledDefinition, int drilledQuantity, SKPointI drillPoint) : base(player) { DrilledDefinition = drilledDefinition; DrilledQuantity = drilledQuantity; @@ -814,9 +810,9 @@ public class SubmitItemEventInfo : MissionEventInfo { public Item SubmittedItem { get; private set; } public MissionStructure SubmitMissionStructure { get; private set; } - public Point SubmitPoint { get; private set; } + public SKPointI SubmitPoint { get; private set; } - public SubmitItemEventInfo(Player player, Item submittedItem, MissionStructure submitMissionStructure, Point submitPoint) : base(player) + public SubmitItemEventInfo(Player player, Item submittedItem, MissionStructure submitMissionStructure, SKPointI submitPoint) : base(player) { SubmittedItem = submittedItem; SubmitMissionStructure = submitMissionStructure; @@ -910,9 +906,9 @@ protected override Dictionary ToDictionary() public class SwitchEventInfo : MissionEventInfo { public MissionStructure SwitchMissionStructure { get; private set; } - public Point SwitchPosition { get; private set; } + public SKPointI SwitchPosition { get; private set; } - public SwitchEventInfo(Player player, MissionStructure switchMissionStructure, Point switchPosition) : base(player) + public SwitchEventInfo(Player player, MissionStructure switchMissionStructure, SKPointI switchPosition) : base(player) { SwitchMissionStructure = switchMissionStructure; SwitchPosition = switchPosition; @@ -955,9 +951,9 @@ public class ItemSupplyEventInfo : MissionEventInfo { public Item SuppliedItem { get; private set; } public MissionStructure ItemSupplyStructure { get; private set; } - public Point SupplyPoint { get; private set; } + public SKPointI SupplyPoint { get; private set; } - public ItemSupplyEventInfo(Player player, Item suppliedItem, MissionStructure itemSupplyStructure, Point supplyPoint) : base(player) + public ItemSupplyEventInfo(Player player, Item suppliedItem, MissionStructure itemSupplyStructure, SKPointI supplyPoint) : base(player) { SuppliedItem = suppliedItem; ItemSupplyStructure = itemSupplyStructure; @@ -1032,9 +1028,9 @@ public int GetCurrentProgress() public class FindArtifactEventInfo : MissionEventInfo { public ArtifactType FoundArtifactType { get; private set; } - public Point ArtifactPoint { get; private set; } + public SKPointI ArtifactPoint { get; private set; } - public FindArtifactEventInfo(Player player, ArtifactType foundArtifactType, Point artifactPoint) : base(player) + public FindArtifactEventInfo(Player player, ArtifactType foundArtifactType, SKPointI artifactPoint) : base(player) { FoundArtifactType = foundArtifactType; ArtifactPoint = artifactPoint; @@ -1124,9 +1120,9 @@ protected override void OnTargetComplete() public class SummonEggEventInfo : MissionEventInfo { public int SummonedEggDefinition { get; private set; } - public Point SummonedPoint { get; private set; } + public SKPointI SummonedPoint { get; private set; } - public SummonEggEventInfo(Player player, int summonedEggDefinition, Point summonedPoint) : base(player) + public SummonEggEventInfo(Player player, int summonedEggDefinition, SKPointI summonedPoint) : base(player) { SummonedEggDefinition = summonedEggDefinition; SummonedPoint = summonedPoint; diff --git a/src/Perpetuum/Services/Relics/RelicManagers/AbstractRelicManager.cs b/src/Perpetuum/Services/Relics/RelicManagers/AbstractRelicManager.cs index 922a83d..3d26812 100644 --- a/src/Perpetuum/Services/Relics/RelicManagers/AbstractRelicManager.cs +++ b/src/Perpetuum/Services/Relics/RelicManagers/AbstractRelicManager.cs @@ -1,11 +1,7 @@ using Perpetuum.Zones; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Drawing; using Perpetuum.Log; -using System.Threading; using Perpetuum.Threading; +using SkiaSharp; namespace Perpetuum.Services.Relics { @@ -112,7 +108,7 @@ protected virtual List> DoGetRelicListDictionary() //Abstract methods for extension of behaviour' protected abstract void RefreshBeam(IRelic relic); - protected abstract Point FindRelicPosition(RelicInfo info); + protected abstract SKPointI FindRelicPosition(RelicInfo info); protected abstract RelicInfo GetNextRelicType(); @@ -152,7 +148,7 @@ private void SpawnRelic() } attempts = 0; - Point pt = FindRelicPosition(info); + SKPointI pt = FindRelicPosition(info); while (IsSpawnTooClose(pt) || !IsValidPos(pt)) { pt = FindRelicPosition(info); @@ -166,7 +162,7 @@ private void SpawnRelic() AddRelicToZone(info, pt.ToPosition()); } - private bool IsValidPos(Point pt) + private bool IsValidPos(SKPointI pt) { return Zone.IsWalkable(pt); } @@ -183,7 +179,7 @@ private void AddRelicToZone(RelicInfo info, Position position) } } - private bool IsSpawnTooClose(Point point) + private bool IsSpawnTooClose(SKPointI point) { using (Lock.Read(THREAD_TIMEOUT)) { diff --git a/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs b/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs index 2fd17e9..89c8135 100644 --- a/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs +++ b/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs @@ -1,12 +1,9 @@ using Perpetuum.Zones; -using System; -using System.Collections.Generic; -using System.Drawing; using Perpetuum.ExportedTypes; using Perpetuum.Zones.Beams; using Perpetuum.Zones.Intrusion; using Perpetuum.Zones.Finders.PositionFinders; -using System.Threading; +using SkiaSharp; namespace Perpetuum.Services.Relics { @@ -75,7 +72,7 @@ protected override RelicInfo GetNextRelicType() return _sapRelicInfo; } - protected override Point FindRelicPosition(RelicInfo info) + protected override SKPointI FindRelicPosition(RelicInfo info) { for(int i = 0; i < 10; i++) { @@ -84,13 +81,13 @@ protected override Point FindRelicPosition(RelicInfo info) var posFinder = new ClosestWalkablePositionFinder(_zone, randomPos); posFinder.Find(out Position p); - var result = _zone.FindWalkableArea(p, _zone.Size.ToArea(), SPAWN_AREA_REQUIRED_SIZE); + var result = _zone.FindWalkableArea(p, new Area(0, 0, _zone.Size.Width, _zone.Size.Height), SPAWN_AREA_REQUIRED_SIZE); if(result != null) { return p; } } - return Point.Empty; + return SKPointI.Empty; } protected override void RefreshBeam(IRelic relic) diff --git a/src/Perpetuum/Services/Relics/RelicManagers/ZoneRelicManager.cs b/src/Perpetuum/Services/Relics/RelicManagers/ZoneRelicManager.cs index 71112f2..dc7cbf4 100644 --- a/src/Perpetuum/Services/Relics/RelicManagers/ZoneRelicManager.cs +++ b/src/Perpetuum/Services/Relics/RelicManagers/ZoneRelicManager.cs @@ -3,7 +3,7 @@ using Perpetuum.Zones; using Perpetuum.Zones.Beams; using Perpetuum.Zones.Intrusion; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Services.Relics.RelicManagers { @@ -127,7 +127,7 @@ protected override RelicInfo GetNextRelicType() return info; } - protected override Point FindRelicPosition(RelicInfo info) + protected override SKPointI FindRelicPosition(RelicInfo info) { if (info.HasStaticPosistion) //If the relic spawn info has a valid static position defined - use that { diff --git a/src/Perpetuum/Services/RiftSystem/RiftManager.cs b/src/Perpetuum/Services/RiftSystem/RiftManager.cs index fa2411e..dc90a5a 100644 --- a/src/Perpetuum/Services/RiftSystem/RiftManager.cs +++ b/src/Perpetuum/Services/RiftSystem/RiftManager.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Threading; using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; using Perpetuum.Log; @@ -9,6 +5,7 @@ using Perpetuum.Units; using Perpetuum.Zones; using Perpetuum.Zones.Terrains; +using SkiaSharp; namespace Perpetuum.Services.RiftSystem { @@ -22,12 +19,12 @@ protected RiftSpawnPositionFinder(IZone zone) _zone = zone; } - public Point FindSpawnPosition() + public SKPointI FindSpawnPosition() { return FindSpawnPosition(_zone); } - protected abstract Point FindSpawnPosition(IZone zone); + protected abstract SKPointI FindSpawnPosition(IZone zone); } public class PveRiftSpawnPositionFinder : RiftSpawnPositionFinder @@ -36,7 +33,7 @@ public PveRiftSpawnPositionFinder(IZone zone) : base(zone) { } - protected override Point FindSpawnPosition(IZone zone) + protected override SKPointI FindSpawnPosition(IZone zone) { return zone.GetRandomPassablePosition(); } @@ -48,9 +45,9 @@ public PvpRiftSpawnPositionFinder(IZone zone) : base(zone) { } - protected override Point FindSpawnPosition(IZone zone) + protected override SKPointI FindSpawnPosition(IZone zone) { - var p = zone.FindWalkableArea(zone.Size.ToArea(), 20); + var p = zone.FindWalkableArea(new Area(0, 0, zone.Size.Width, zone.Size.Height), 20); return p.RandomElement(); } } diff --git a/src/Perpetuum/SizeExtensions.cs b/src/Perpetuum/SizeExtensions.cs index e80160a..73f2bfa 100644 --- a/src/Perpetuum/SizeExtensions.cs +++ b/src/Perpetuum/SizeExtensions.cs @@ -1,31 +1,31 @@ using Perpetuum.Zones; -using System.Drawing; +using SkiaSharp; namespace Perpetuum { public static class SizeExtensions { - public static bool Contains(this Size size, Point p) + public static bool Contains(this SKSizeI size, SKPointI p) { return Contains(size, p.X, p.Y); } - public static bool Contains(this Size size, int x, int y) + public static bool Contains(this SKSizeI size, int x, int y) { return x >= 0 && x < size.Width && y >= 0 && y < size.Height; } - public static Point GetCenter(this Size size) + public static SKPointI GetCenter(this SKSizeI size) { - return new Point(size.Width / 2, size.Height / 2); + return new SKPointI(size.Width / 2, size.Height / 2); } - public static Area ToArea(this Size size) + public static Area ToArea(this SKSizeI size) { return Area.FromRectangle(0, 0, size.Width, size.Height); } - public static Position GetRandomPosition(this Size size, int margin) + public static Position GetRandomPosition(this SKSizeI size, int margin) { int minX = 0 + margin; int maxX = size.Width - margin; @@ -37,25 +37,25 @@ public static Position GetRandomPosition(this Size size, int margin) } [System.Diagnostics.Contracts.Pure] - public static int Ground(this Size size) + public static int Ground(this SKSizeI size) { return size.Width * size.Height; } [System.Diagnostics.Contracts.Pure] - public static T[] CreateArray(this Size size) + public static T[] CreateArray(this SKSizeI size) { return new T[size.Width * size.Height]; } [System.Diagnostics.Contracts.Pure] - public static T[,] Create2DArray(this Size size) + public static T[,] Create2DArray(this SKSizeI size) { return new T[size.Width, size.Height]; } [System.Diagnostics.Contracts.Pure] - public static double Diagonal(this Size size) + public static double Diagonal(this SKSizeI size) { return Math.Sqrt((size.Width * size.Width) + (size.Height * size.Height)); } diff --git a/src/Perpetuum/StateMachines/IState.cs b/src/Perpetuum/StateMachines/IState.cs index 0b3e934..ac09170 100644 --- a/src/Perpetuum/StateMachines/IState.cs +++ b/src/Perpetuum/StateMachines/IState.cs @@ -1,5 +1,3 @@ -using System; - namespace Perpetuum.StateMachines { public interface IState diff --git a/src/Perpetuum/Zones/Artifacts/Artifact.cs b/src/Perpetuum/Zones/Artifacts/Artifact.cs index 64aae74..d6a8a87 100644 --- a/src/Perpetuum/Zones/Artifacts/Artifact.cs +++ b/src/Perpetuum/Zones/Artifacts/Artifact.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using Perpetuum.Accounting.Characters; +using Perpetuum.Accounting.Characters; namespace Perpetuum.Zones.Artifacts { diff --git a/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs b/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs index ad5f1ee..82e8f10 100644 --- a/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs +++ b/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs @@ -1,11 +1,10 @@ -using System.Drawing; -using System.Linq; using Perpetuum.Data; using Perpetuum.ExportedTypes; using Perpetuum.Log; using Perpetuum.Players; using Perpetuum.Zones.Artifacts.Repositories; using Perpetuum.Zones.Terrains; +using SkiaSharp; namespace Perpetuum.Zones.Artifacts.Generators { @@ -74,7 +73,7 @@ private ArtifactType GetNextArtifactType() return ArtifactType.undefined; } - private static Point FindArtifactPosition(IZone zone) + private static SKPointI FindArtifactPosition(IZone zone) { if (!zone.Configuration.Terraformable) { @@ -82,7 +81,7 @@ private static Point FindArtifactPosition(IZone zone) } // gamman keresunk teruletet - var p = zone.FindWalkableArea(zone.Size.ToArea(), 20); + var p = zone.FindWalkableArea(new Area(0, 0, zone.Size.Width, zone.Size.Height), 20); return p.RandomElement(); } diff --git a/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanResult.cs b/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanResult.cs index 0861938..63dcfcd 100644 --- a/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanResult.cs +++ b/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanResult.cs @@ -1,4 +1,4 @@ -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.Artifacts.Scanners { @@ -8,7 +8,7 @@ namespace Perpetuum.Zones.Artifacts.Scanners public class ArtifactScanResult { public Artifact scannedArtifact; - public Point estimatedPosition; + public SKPointI estimatedPosition; public double radius; } } \ No newline at end of file diff --git a/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanner.cs b/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanner.cs index cef32bb..f1560fb 100644 --- a/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanner.cs +++ b/src/Perpetuum/Zones/Artifacts/Scanners/ArtifactScanner.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections.Generic; using Perpetuum.ExportedTypes; using Perpetuum.Players; using Perpetuum.Services.Looting; diff --git a/src/Perpetuum/Zones/Beams/BeamBuilder.cs b/src/Perpetuum/Zones/Beams/BeamBuilder.cs index c331b7b..6e6df6b 100644 --- a/src/Perpetuum/Zones/Beams/BeamBuilder.cs +++ b/src/Perpetuum/Zones/Beams/BeamBuilder.cs @@ -1,8 +1,7 @@ -using System; -using System.Drawing; using Perpetuum.Builders; using Perpetuum.ExportedTypes; using Perpetuum.Units; +using SkiaSharp; namespace Perpetuum.Zones.Beams { @@ -106,7 +105,7 @@ public BeamBuilder WithDuration(TimeSpan duration) return this; } - public BeamBuilder WithPosition(Point position) + public BeamBuilder WithPosition(SKPointI position) { return WithSourcePosition(position.ToPosition()).WithTargetPosition(position.ToPosition()); } diff --git a/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs b/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs index e7f8fe7..cb02c8a 100644 --- a/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs +++ b/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs @@ -21,7 +21,7 @@ public RandomWalkableAroundPositionFinder(IZone zone, Position origin, int range _slope = slope; _origin = origin; _maxRange = range; - _zoneArea = zone.Size.ToArea(); + _zoneArea = new Area(0, 0, zone.Size.Width, zone.Size.Height); } protected Position FindClosestWalkable(IZone zone, Position pos) diff --git a/src/Perpetuum/Zones/IZone.cs b/src/Perpetuum/Zones/IZone.cs index 4a40afd..9fd0e56 100644 --- a/src/Perpetuum/Zones/IZone.cs +++ b/src/Perpetuum/Zones/IZone.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; -using System.Drawing; using Perpetuum.Accounting.Characters; using Perpetuum.Common.Loggers; using Perpetuum.Groups.Corporations; using Perpetuum.Log; using Perpetuum.Players; using Perpetuum.Services.Relics; -using Perpetuum.Services.Strongholds; using Perpetuum.Services.Weather; using Perpetuum.Units; using Perpetuum.Zones.Beams; @@ -20,6 +17,7 @@ using Perpetuum.Zones.Terrains.Materials.Plants; using Perpetuum.Zones.Terrains.Terraforming; using Perpetuum.Zones.ZoneEntityRepositories; +using SkiaSharp; namespace Perpetuum.Zones { @@ -29,7 +27,7 @@ public interface IZone bool IsLayerEditLocked { get; set; } int Id { get; } - Size Size { get; } + SKSizeI Size { get; } IEnumerable Units { get; } IEnumerable Players { get; } diff --git a/src/Perpetuum/Zones/Movements/PathMovement.cs b/src/Perpetuum/Zones/Movements/PathMovement.cs index 7af8ad0..e2d8517 100644 --- a/src/Perpetuum/Zones/Movements/PathMovement.cs +++ b/src/Perpetuum/Zones/Movements/PathMovement.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using System.Numerics; using Perpetuum.Units; +using SkiaSharp; namespace Perpetuum.Zones.Movements { @@ -12,7 +9,7 @@ public class PathMovement : Movement private readonly Queue _path = new Queue(); private WaypointMovement _movement; - public PathMovement(IEnumerable path) + public PathMovement(IEnumerable path) { foreach (var point in path.Skip(1)) { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/BaseAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/BaseAI.cs index ab74717..b9f6e2e 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/BaseAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/BaseAI.cs @@ -4,10 +4,7 @@ using Perpetuum.Zones.NpcSystem.AI.Behaviors; using Perpetuum.Zones.NpcSystem.AI.IndustrialDrones; using Perpetuum.Zones.RemoteControl; -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; namespace Perpetuum.Zones.NpcSystem.AI { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/CombatAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/CombatAI.cs index ef65fa1..860e9d7 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/CombatAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/CombatAI.cs @@ -10,7 +10,7 @@ using Perpetuum.Zones.NpcSystem.TargettingStrategies; using Perpetuum.Zones.NpcSystem.ThreatManaging; using Perpetuum.Zones.Terrains; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI { @@ -225,7 +225,7 @@ protected virtual void ReturnToHomePosition() WriteLog("Enter evade mode."); } - protected Task> FindNewAttackPositionAsync(Unit hostile) + protected Task> FindNewAttackPositionAsync(Unit hostile) { source?.Cancel(); source = new CancellationTokenSource(); @@ -286,7 +286,7 @@ protected void UpdateHostile(TimeSpan time, bool moveThreatToPseudoThreat = true return; } - List path = t.Result; + List path = t.Result; if (path == null) { @@ -370,9 +370,9 @@ private bool SelectPrimaryTarget() return validLocks.Length >= 1 && (stratSelector?.TryUseStrategy(smartCreature, validLocks) ?? false); } - private List FindNewAttackPosition(Unit hostile, CancellationToken cancellationToken) + private List FindNewAttackPosition(Unit hostile, CancellationToken cancellationToken) { - Point end = hostile.CurrentPosition.GetRandomPositionInRange2D(0, smartCreature.BestActionRange - 1).ToPoint(); + SKPointI end = hostile.CurrentPosition.GetRandomPositionInRange2D(0, smartCreature.BestActionRange - 1).ToPoint(); smartCreature.StopMoving(); // Nulling movement so that the unit does not resume it at zero speed if the path is not found. @@ -384,7 +384,7 @@ private List FindNewAttackPosition(Unit hostile, CancellationToken cancel priorityQueue.Enqueue(startNode); - HashSet closed = + HashSet closed = [ startNode.position ]; @@ -402,7 +402,7 @@ private List FindNewAttackPosition(Unit hostile, CancellationToken cancel return BuildPath(current); } - foreach (Point n in current.position.GetNeighbours()) + foreach (SKPointI n in current.position.GetNeighbours()) { if (closed.Contains(n)) { @@ -437,7 +437,7 @@ private List FindNewAttackPosition(Unit hostile, CancellationToken cancel return null; } - private bool IsValidAttackPosition(Unit hostile, Point position) + private bool IsValidAttackPosition(Unit hostile, SKPointI position) { Position position3 = smartCreature.Zone.FixZ(position.ToPosition()).AddToZ(smartCreature.Height); @@ -451,9 +451,9 @@ private bool IsValidAttackPosition(Unit hostile, Point position) return !r.hit; } - private static List BuildPath(Node current) + private static List BuildPath(Node current) { - Stack stack = new(); + Stack stack = new(); Node node = current; while (node != null) diff --git a/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/CombatDroneAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/CombatDroneAI.cs index e0f5315..145aa14 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/CombatDroneAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/CombatDroneAI.cs @@ -6,7 +6,7 @@ using Perpetuum.Zones.Locking.Locks; using Perpetuum.Zones.Movements; using Perpetuum.Zones.RemoteControl; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI.CombatDrones { @@ -131,7 +131,7 @@ protected virtual void ReturnToHomePosition() WriteLog("Enter evade mode."); } - protected Task> FindNewAttackPositionAsync(Unit hostile) + protected Task> FindNewAttackPositionAsync(Unit hostile) { source?.Cancel(); source = new CancellationTokenSource(); @@ -192,7 +192,7 @@ protected void UpdateHostile(TimeSpan time) return; } - List path = t.Result; + List path = t.Result; if (path == null) { @@ -254,9 +254,9 @@ private bool SetLock(UnitLock unitLock) return isNewLock; } - private List FindNewAttackPosition(Unit hostile, CancellationToken cancellationToken) + private List FindNewAttackPosition(Unit hostile, CancellationToken cancellationToken) { - Point end = hostile.CurrentPosition.GetRandomPositionInRange2D(0, smartCreature.BestActionRange - 1).ToPoint(); + SKPointI end = hostile.CurrentPosition.GetRandomPositionInRange2D(0, smartCreature.BestActionRange - 1).ToPoint(); smartCreature.StopMoving(); // Nulling movement so that the unit does not resume it at zero speed if the path is not found. @@ -268,7 +268,7 @@ private List FindNewAttackPosition(Unit hostile, CancellationToken cancel priorityQueue.Enqueue(startNode); - HashSet closed = new HashSet + HashSet closed = new HashSet { startNode.position }; @@ -286,7 +286,7 @@ private List FindNewAttackPosition(Unit hostile, CancellationToken cancel return BuildPath(current); } - foreach (Point n in current.position.GetNeighbours()) + foreach (SKPointI n in current.position.GetNeighbours()) { if (closed.Contains(n)) { @@ -321,7 +321,7 @@ private List FindNewAttackPosition(Unit hostile, CancellationToken cancel return null; } - private bool IsValidAttackPosition(Unit hostile, Point position) + private bool IsValidAttackPosition(Unit hostile, SKPointI position) { Position position3 = smartCreature.Zone.FixZ(position.ToPosition()).AddToZ(smartCreature.Height); @@ -335,9 +335,9 @@ private bool IsValidAttackPosition(Unit hostile, Point position) return !r.hit; } - private static List BuildPath(Node current) + private static List BuildPath(Node current) { - Stack stack = new Stack(); + Stack stack = new Stack(); Node node = current; while (node != null) diff --git a/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/EscortCombatDroneAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/EscortCombatDroneAI.cs index a3f679b..fe57b21 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/EscortCombatDroneAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/EscortCombatDroneAI.cs @@ -1,6 +1,7 @@ using Perpetuum.PathFinders; using Perpetuum.Zones.Movements; using Perpetuum.Zones.RemoteControl; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI.CombatDrones { @@ -29,7 +30,7 @@ public override void Enter() .FindPathAsync(smartCreature.CurrentPosition, randomHome) .ContinueWith(t => { - System.Drawing.Point[] path = t.Result; + SKPointI[] path = t.Result; if (path == null) { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/RetreatCombatDroneAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/RetreatCombatDroneAI.cs index 075049c..5c10a30 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/RetreatCombatDroneAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/CombatDrones/RetreatCombatDroneAI.cs @@ -1,7 +1,7 @@ using Perpetuum.PathFinders; using Perpetuum.Zones.Movements; using Perpetuum.Zones.RemoteControl; -using System; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI.CombatDrones { @@ -31,7 +31,7 @@ public override void Enter() .FindPathAsync(smartCreature.CurrentPosition, randomHome) .ContinueWith(t => { - System.Drawing.Point[] path = t.Result; + SKPointI[] path = t.Result; if (path == null) { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/HomingAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/HomingAI.cs index 63a2dcd..20f6486 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/HomingAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/HomingAI.cs @@ -1,9 +1,7 @@ using Perpetuum.Modules; using Perpetuum.PathFinders; using Perpetuum.Zones.Movements; -using System; -using System.Collections.Generic; -using System.Linq; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI { @@ -33,7 +31,7 @@ public override void Enter() .FindPathAsync(smartCreature.CurrentPosition, randomHome) .ContinueWith(t => { - System.Drawing.Point[] path = t.Result; + SKPointI[] path = t.Result; if (path == null) { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/IndustrialAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/IndustrialAI.cs index 80a5e30..5fa8905 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/IndustrialAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/IndustrialAI.cs @@ -6,12 +6,7 @@ using Perpetuum.Zones.Movements; using Perpetuum.Zones.NpcSystem.AI.IndustrialDrones; using Perpetuum.Zones.RemoteControl; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI { @@ -137,7 +132,7 @@ protected void UpdateIndustrialTarget(TimeSpan time) return; } - List path = t.Result; + List path = t.Result; if (path == null) { @@ -177,7 +172,7 @@ protected void EjectCargo(TimeSpan time) } } - protected Task> FindNewAttackPositionAsync(Position position) + protected Task> FindNewAttackPositionAsync(Position position) { source?.Cancel(); source = new CancellationTokenSource(); @@ -226,9 +221,9 @@ private bool SetLock(TerrainLock terrainLock) return isNewLock; } - private List FindNewAttackPosition(Position position, CancellationToken cancellationToken) + private List FindNewAttackPosition(Position position, CancellationToken cancellationToken) { - Point end = position.GetRandomPositionInRange2D(0, smartCreature.BestActionRange - 1).ToPoint(); + SKPointI end = position.GetRandomPositionInRange2D(0, smartCreature.BestActionRange - 1).ToPoint(); smartCreature.StopMoving(); // Nulling movement so that the unit does not resume it at zero speed if the path is not found. @@ -240,7 +235,7 @@ private List FindNewAttackPosition(Position position, CancellationToken c priorityQueue.Enqueue(startNode); - HashSet closed = new HashSet + HashSet closed = new HashSet { startNode.position }; @@ -258,7 +253,7 @@ private List FindNewAttackPosition(Position position, CancellationToken c return BuildPath(current); } - foreach (Point n in current.position.GetNeighbours()) + foreach (SKPointI n in current.position.GetNeighbours()) { if (closed.Contains(n)) { @@ -293,7 +288,7 @@ private List FindNewAttackPosition(Position position, CancellationToken c return null; } - private bool IsValidAttackPosition(Position targetPosition, Point position) + private bool IsValidAttackPosition(Position targetPosition, SKPointI position) { Position position3 = smartCreature.Zone.FixZ(position.ToPosition()).AddToZ(smartCreature.Height); @@ -307,9 +302,9 @@ private bool IsValidAttackPosition(Position targetPosition, Point position) return !r.hit; } - private static List BuildPath(Node current) + private static List BuildPath(Node current) { - Stack stack = new Stack(); + Stack stack = new Stack(); Node node = current; while (node != null) diff --git a/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/EscortIndustrialDroneAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/EscortIndustrialDroneAI.cs index 1516137..bcc2aef 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/EscortIndustrialDroneAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/EscortIndustrialDroneAI.cs @@ -1,7 +1,7 @@ using Perpetuum.PathFinders; using Perpetuum.Zones.Movements; using Perpetuum.Zones.RemoteControl; -using System; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI.IndustrialDrones { @@ -30,7 +30,7 @@ public override void Enter() .FindPathAsync(smartCreature.CurrentPosition, randomHome) .ContinueWith(t => { - System.Drawing.Point[] path = t.Result; + SKPointI[] path = t.Result; if (path == null) { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/RetreatIndustrialDroneAI.cs b/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/RetreatIndustrialDroneAI.cs index d511814..a8a5b50 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/RetreatIndustrialDroneAI.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/IndustrialDrones/RetreatIndustrialDroneAI.cs @@ -1,7 +1,7 @@ using Perpetuum.PathFinders; using Perpetuum.Zones.Movements; using Perpetuum.Zones.RemoteControl; -using System; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI.IndustrialDrones { @@ -31,7 +31,7 @@ public override void Enter() .FindPathAsync(smartCreature.CurrentPosition, randomHome) .ContinueWith(t => { - System.Drawing.Point[] path = t.Result; + SKPointI[] path = t.Result; if (path == null) { diff --git a/src/Perpetuum/Zones/NpcSystem/AI/Node.cs b/src/Perpetuum/Zones/NpcSystem/AI/Node.cs index 36cb79c..9a7362c 100644 --- a/src/Perpetuum/Zones/NpcSystem/AI/Node.cs +++ b/src/Perpetuum/Zones/NpcSystem/AI/Node.cs @@ -1,16 +1,15 @@ -using System; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.AI { public class Node : IComparable { - public readonly Point position; + public readonly SKPointI position; public Node parent; public int g; public int f; - public Node(Point position) + public Node(SKPointI position) { this.position = position; } diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs b/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs index 0842cf6..b57a0d1 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs @@ -1,7 +1,6 @@ -using System; -using System.Linq; using Perpetuum.Timers; using Perpetuum.Zones.NpcSystem.Flocks; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences { @@ -57,7 +56,7 @@ public DynamicPresence(IZone zone, IPresenceConfiguration configuration) : base( public override Area Area { - get { return Zone.Size.ToArea(); } + get { return new Area(0, 0, Zone.Size.Width, Zone.Size.Height); } } protected override void OnPresenceExpired() diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/ExpiringStaticPresence/RandomSpawningExpiringPresence.cs b/src/Perpetuum/Zones/NpcSystem/Presences/ExpiringStaticPresence/RandomSpawningExpiringPresence.cs index d8dbd10..f08a7c8 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/ExpiringStaticPresence/RandomSpawningExpiringPresence.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/ExpiringStaticPresence/RandomSpawningExpiringPresence.cs @@ -1,8 +1,7 @@ using Perpetuum.StateMachines; using Perpetuum.Zones.NpcSystem.Presences.PathFinders; -using System; -using System.Drawing; using Perpetuum.Zones.NpcSystem.Presences.ExpiringStaticPresence; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences.RandomExpiringPresence { @@ -15,7 +14,7 @@ public class RandomSpawningExpiringPresence : ExpiringPresence, IRandomStaticPre public Position SpawnOrigin { get; set; } public IRoamingPathFinder PathFinder { get; set; } public override Area Area => Configuration.Area; - public Point CurrentRoamingPosition { get; set; } + public SKPointI CurrentRoamingPosition { get; set; } public RandomSpawningExpiringPresence(IZone zone, IPresenceConfiguration configuration) : base(zone, configuration) { diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/InterzonePresences/InterzonePresence.cs b/src/Perpetuum/Zones/NpcSystem/Presences/InterzonePresences/InterzonePresence.cs index 76b13e6..6282997 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/InterzonePresences/InterzonePresence.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/InterzonePresences/InterzonePresence.cs @@ -1,9 +1,8 @@ -using System; -using System.Text; -using System.Drawing; +using System.Text; using Perpetuum.StateMachines; using Perpetuum.Zones.NpcSystem.Flocks; using Perpetuum.Zones.NpcSystem.Presences.PathFinders; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences.InterzonePresences { @@ -11,7 +10,7 @@ public class InterzoneRoamingPresence : InterzonePresence, IRoamingPresence { public StackFSM StackFSM { get; } public Position SpawnOrigin { get; set; } - public Point CurrentRoamingPosition { get; set; } + public SKPointI CurrentRoamingPosition { get; set; } public IRoamingPathFinder PathFinder { get; set; } public InterzoneRoamingPresence(IZone zone, IPresenceConfiguration configuration) : base(zone, configuration) { diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/FreeRoamingPathFinder.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/FreeRoamingPathFinder.cs index 1f8356b..ef324e3 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/FreeRoamingPathFinder.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/FreeRoamingPathFinder.cs @@ -1,14 +1,11 @@ //#define VERBOSE -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using Perpetuum.Collections; using Perpetuum.ExportedTypes; using Perpetuum.Log; using Perpetuum.PathFinders; using Perpetuum.Zones.NpcSystem.Flocks; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences.PathFinders { @@ -49,7 +46,7 @@ private double TryGetMinSlope(IRoamingPresence presence) return ZoneExtensions.MIN_SLOPE; } - public Point FindSpawnPosition(IRoamingPresence presence) + public SKPointI FindSpawnPosition(IRoamingPresence presence) { var homeRange = TryGetMaxHomeRange(presence); var rangeMax = homeRange * 2; @@ -58,7 +55,7 @@ public Point FindSpawnPosition(IRoamingPresence presence) return walkableArea.RandomElement(); } - public Point FindNextRoamingPosition(IRoamingPresence presence) + public SKPointI FindNextRoamingPosition(IRoamingPresence presence) { var minSlope = TryGetMinSlope(presence); var maxHomeRange = TryGetMaxHomeRange(presence); @@ -68,7 +65,7 @@ public Point FindNextRoamingPosition(IRoamingPresence presence) var startNode = new Node(presence.CurrentRoamingPosition); queue.Enqueue(startNode); - var closed = new HashSet {presence.CurrentRoamingPosition}; + var closed = new HashSet {presence.CurrentRoamingPosition}; if (FastRandom.NextDouble() < 0.3) { @@ -116,10 +113,10 @@ public Point FindNextRoamingPosition(IRoamingPresence presence) private struct Node : IComparable { - public readonly Point location; + public readonly SKPointI location; private readonly int _cost; - public Node(Point location,int cost = 0) + public Node(SKPointI location,int cost = 0) { this.location = location; _cost = cost; diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/IRoamingPathFinder.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/IRoamingPathFinder.cs index 2c296c4..19d0185 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/IRoamingPathFinder.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/IRoamingPathFinder.cs @@ -1,10 +1,10 @@ -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences.PathFinders { public interface IRoamingPathFinder { - Point FindSpawnPosition(IRoamingPresence presence); - Point FindNextRoamingPosition(IRoamingPresence presence); + SKPointI FindSpawnPosition(IRoamingPresence presence); + SKPointI FindNextRoamingPosition(IRoamingPresence presence); } } \ No newline at end of file diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/NormalRoamingPathFinder.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/NormalRoamingPathFinder.cs index d0495b8..a6b35c9 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/NormalRoamingPathFinder.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/NormalRoamingPathFinder.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using Perpetuum.Collections; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences.PathFinders { @@ -17,13 +14,13 @@ public NormalRoamingPathFinder(IZone zone) _zone = zone; } - public Point FindSpawnPosition(IRoamingPresence presence) + public SKPointI FindSpawnPosition(IRoamingPresence presence) { var point = _zone.SafeSpawnPoints.GetAll().RandomElement(); return point.Location; } - public Point FindNextRoamingPosition(IRoamingPresence presence) + public SKPointI FindNextRoamingPosition(IRoamingPresence presence) { var homeRange = presence.Flocks.Max(f => f.HomeRange); var rangeMax = homeRange * 2; @@ -82,7 +79,7 @@ public Point FindNextRoamingPosition(IRoamingPresence presence) return startNode.position; } - private int CalculateCost(Point from, Point position) + private int CalculateCost(SKPointI from, SKPointI position) { var dx = Math.Abs(position.X - from.X); var dy = Math.Abs(position.Y - from.Y); @@ -97,7 +94,7 @@ private int CalculateCost(Point from, Point position) return cost; } - private bool IsRoamingPosition(Point roamingPosition) + private bool IsRoamingPosition(SKPointI roamingPosition) { var isRoaming = _zone.Terrain.Controls[roamingPosition.X,roamingPosition.Y].Roaming; var isWalkable = _zone.IsWalkable(roamingPosition.X, roamingPosition.Y); @@ -106,14 +103,14 @@ private bool IsRoamingPosition(Point roamingPosition) private struct Node : IComparable { - public readonly Point position; + public readonly SKPointI position; public int cost; - public Node(int x, int y) : this(new Point(x, y)) + public Node(int x, int y) : this(new SKPointI(x, y)) { } - public Node(Point position) + public Node(SKPointI position) { this.position = position; cost = 0; diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/RoamingState.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/RoamingState.cs index 9f05339..dcef1ad 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/RoamingState.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/RoamingState.cs @@ -1,7 +1,5 @@ using Perpetuum.Zones.NpcSystem.AI; using Perpetuum.Zones.NpcSystem.Flocks; -using System; -using System.Linq; namespace Perpetuum.Zones.NpcSystem.Presences.PathFinders { diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs index b681040..9c78869 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs @@ -48,7 +48,7 @@ public class DirectPresenceConfiguration : PresenceConfiguration public DirectPresenceConfiguration(IZone zone) : base(_idGenerator.GetNextID(), PresenceType.Direct) { - Area = zone.Configuration.Size.ToArea(); + Area = new Area(0, 0, zone.Size.Width, zone.Size.Height); Name = "direct presence " + ID; SpawnId = 10; //dynamic kamubol, szerintem kicsit sem kell Note = "abs! rulez"; diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/RoamingPresence.cs b/src/Perpetuum/Zones/NpcSystem/Presences/RoamingPresence.cs index e3a8a58..961e6fb 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/RoamingPresence.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/RoamingPresence.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Drawing; using Perpetuum.StateMachines; using Perpetuum.Zones.NpcSystem.Flocks; using Perpetuum.Zones.NpcSystem.Presences.PathFinders; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.Presences { @@ -11,7 +9,7 @@ public interface IRoamingPresence { StackFSM StackFSM { get; } Position SpawnOrigin { get; set; } - Point CurrentRoamingPosition { get; set; } + SKPointI CurrentRoamingPosition { get; set; } IRoamingPathFinder PathFinder { get; set; } IPresenceConfiguration Configuration { get; } IZone Zone { get; } @@ -25,7 +23,7 @@ public class RoamingPresence : Presence, IRoamingPresence { public StackFSM StackFSM { get; } public Position SpawnOrigin { get; set; } - public Point CurrentRoamingPosition { get; set; } + public SKPointI CurrentRoamingPosition { get; set; } public IRoamingPathFinder PathFinder { get; set; } public override Area Area => Configuration.Area; diff --git a/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/ISafeSpawnPointsRepository.cs b/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/ISafeSpawnPointsRepository.cs index a3eb214..2a23351 100644 --- a/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/ISafeSpawnPointsRepository.cs +++ b/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/ISafeSpawnPointsRepository.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; - namespace Perpetuum.Zones.NpcSystem.SafeSpawnPoints { public interface ISafeSpawnPointsRepository diff --git a/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/NpcSafeSpawnPointsRepository.cs b/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/NpcSafeSpawnPointsRepository.cs index d716af9..3449cb1 100644 --- a/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/NpcSafeSpawnPointsRepository.cs +++ b/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/NpcSafeSpawnPointsRepository.cs @@ -1,7 +1,5 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using Perpetuum.Data; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.SafeSpawnPoints { @@ -45,7 +43,7 @@ public IEnumerable GetAll() { Id = r.GetValue("id"), ZoneId = r.GetValue("zoneId"), - Location = new Point(r.GetValue("x"), r.GetValue("y")) + Location = new SKPointI(r.GetValue("x"), r.GetValue("y")) }; return point; diff --git a/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/SafeSpawnPoint.cs b/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/SafeSpawnPoint.cs index 1873fdc..2a07482 100644 --- a/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/SafeSpawnPoint.cs +++ b/src/Perpetuum/Zones/NpcSystem/SafeSpawnPoints/SafeSpawnPoint.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.NpcSystem.SafeSpawnPoints { @@ -7,7 +6,7 @@ public struct SafeSpawnPoint { public int Id { get; set; } public int ZoneId { private get; set; } - public Point Location { get; set; } + public SKPointI Location { get; set; } public IDictionary ToDictionary() { diff --git a/src/Perpetuum/Zones/PBS/EnergyWell/PBSEnergyWell.cs b/src/Perpetuum/Zones/PBS/EnergyWell/PBSEnergyWell.cs index 5bf33cc..5f0483e 100644 --- a/src/Perpetuum/Zones/PBS/EnergyWell/PBSEnergyWell.cs +++ b/src/Perpetuum/Zones/PBS/EnergyWell/PBSEnergyWell.cs @@ -1,11 +1,9 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using Perpetuum.Items; +using Perpetuum.Items; using Perpetuum.Log; using Perpetuum.Zones.PBS.Reactors; using Perpetuum.Zones.Terrains.Materials; using Perpetuum.Zones.Terrains.Materials.Minerals; +using SkiaSharp; namespace Perpetuum.Zones.PBS.EnergyWell { @@ -124,7 +122,7 @@ private void SaveToDb() DynamicProperties.Update(k.depleted, IsDepleted ? 1 : 0); } - public List ExtractWithinRange(MineralLayer layer, Point location, int range, uint amount) + public List ExtractWithinRange(MineralLayer layer, SKPointI location, int range, uint amount) { var nodes = layer.GetNodesWithinRange(location, range).OrderBy(n => n.Area.SqrDistance(location)); diff --git a/src/Perpetuum/Zones/Position.cs b/src/Perpetuum/Zones/Position.cs index a16d87e..a57b0a3 100644 --- a/src/Perpetuum/Zones/Position.cs +++ b/src/Perpetuum/Zones/Position.cs @@ -1,6 +1,6 @@ using Perpetuum.Collections.Spatial; -using System.Drawing; using System.Numerics; +using SkiaSharp; namespace Perpetuum.Zones { @@ -32,7 +32,7 @@ public Position(double x, double y, double z = 0.0) public Position Center => new(intX + 0.5, intY + 0.5, _z); - public bool IsValid(Size size) + public bool IsValid(SKSizeI size) { return size.Contains(intX, intY) && intZ >= 0 && intZ < short.MaxValue; } @@ -87,7 +87,7 @@ public double TotalDistance2D(Position p) } [System.Diagnostics.Contracts.Pure] - public double TotalDistance2D(Point p) + public double TotalDistance2D(SKPointI p) { return TotalDistance2D(p.X, p.Y); } @@ -320,7 +320,7 @@ public Position Rotate90CCW() return new Position(_y, -1 * _x, _z); } - public Position Clamp(Size size) + public Position Clamp(SKSizeI size) { return new Position(_x.Clamp(0, size.Width - 1), _y.Clamp(0, size.Height - 1), _z.Clamp(0, short.MaxValue)); } @@ -372,7 +372,7 @@ public Position Clamp(Size size) return new Position(p._x * num, p._y * num, p._z * num); } - public static implicit operator Point(Position p) + public static implicit operator SKPointI(Position p) { return p.ToPoint(); } @@ -424,14 +424,14 @@ public Vector3 ToVector3() return new Vector3((float)_x, (float)_y, (float)_z); } - public Point ToPoint() + public SKPointI ToPoint() { - return new Point((int)_x, (int)_y); + return new SKPointI((int)_x, (int)_y); } - public PointF ToPointF() + public SKPoint ToPointF() { - return new PointF((float)_x, (float)_y); + return new SKPoint((float)_x, (float)_y); } public ulong GetUlongHashCode() @@ -471,7 +471,7 @@ public IEnumerable NonDiagonalNeighbours { -2, 2}, { -1, 2}, { 0, 2 }, { 1, 2 }, { 2, 2 }, }; - public IEnumerable GetEightNeighbours(Size size) + public IEnumerable GetEightNeighbours(SKSizeI size) { return EightNeighbours.Where(np => np.IsValid(size)); } @@ -490,7 +490,7 @@ public IEnumerable EightNeighbours } } - public IEnumerable GetTwentyFourNeighbours(Size size) + public IEnumerable GetTwentyFourNeighbours(SKSizeI size) { return TwentyFourNeighbours.Where(np => np.IsValid(size)); } @@ -536,14 +536,14 @@ public CellCoord ToCellCoord() return CellCoord.FromXY((int)X, (int)Y); } - public double DirectionTo(Point point) + public double DirectionTo(SKPointI point) { - return DirectionTo(point.ToPosition()); + return DirectionTo(new Position(point.X, point.Y)); } - public bool IsInRangeOf2D(Point point, double range) + public bool IsInRangeOf2D(SKPointI point, double range) { - return IsInRangeOf2D(point.ToPosition(), range); + return IsInRangeOf2D(new Position(point.X, point.Y), range); } diff --git a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Artifact.cs b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Artifact.cs index 55e7e4f..876a19b 100644 --- a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Artifact.cs +++ b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Artifact.cs @@ -1,6 +1,4 @@ -using System.Linq; -using System.Threading.Tasks; -using System.Transactions; +using System.Transactions; using Perpetuum.Data; using Perpetuum.EntityFramework; using Perpetuum.Zones.Artifacts.Scanners; diff --git a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Directional.cs b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Directional.cs index 558197a..d09f3d0 100644 --- a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Directional.cs +++ b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Directional.cs @@ -1,8 +1,8 @@ -using System.Drawing; -using Perpetuum.EntityFramework; +using Perpetuum.EntityFramework; using Perpetuum.Zones.Scanning.Ammos; using Perpetuum.Zones.Terrains; using Perpetuum.Zones.Terrains.Materials; +using SkiaSharp; namespace Perpetuum.Zones.Scanning.Scanners { @@ -17,7 +17,7 @@ public void Visit(DirectionalScannerAmmo ammo) var layer = _zone.Terrain.GetMineralLayerOrThrow(ammo.MaterialType); - var nearestMineralPosition = Point.Empty; + var nearestMineralPosition = SKPointI.Empty; var nearestDist = int.MaxValue; foreach (var node in layer.Nodes) @@ -52,12 +52,12 @@ private double RandomizeDirection(double direction) return direction; } - private static Packet BuildPacket(MaterialType materialType, Position fromPosition, Point nearestMineralPosition, double direction, bool isInRange) + private static Packet BuildPacket(MaterialType materialType, Position fromPosition, SKPointI nearestMineralPosition, double direction, bool isInRange) { var packet = new Packet(ZoneCommand.ScanMineralDirectionalResult); packet.AppendInt((int) materialType); packet.AppendPoint(fromPosition); - packet.AppendBool(nearestMineralPosition != Point.Empty); + packet.AppendBool(nearestMineralPosition != SKPointI.Empty); packet.AppendByte((byte) (direction*255)); packet.AppendBool(isInRange); return packet; diff --git a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Intrusion.cs b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Intrusion.cs index 572e6ab..adc5de3 100644 --- a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Intrusion.cs +++ b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.Intrusion.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using Perpetuum.EntityFramework; +using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; using Perpetuum.Units; using Perpetuum.Zones.Intrusion; diff --git a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.OneTile.cs b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.OneTile.cs index 2261f8c..ca3cef1 100644 --- a/src/Perpetuum/Zones/Scanning/Scanners/Scanner.OneTile.cs +++ b/src/Perpetuum/Zones/Scanning/Scanners/Scanner.OneTile.cs @@ -1,8 +1,7 @@ -using System.Drawing; -using System.Linq; -using Perpetuum.EntityFramework; +using Perpetuum.EntityFramework; using Perpetuum.Zones.Scanning.Ammos; using Perpetuum.Zones.Terrains.Materials.Minerals; +using SkiaSharp; namespace Perpetuum.Zones.Scanning.Scanners { @@ -17,7 +16,7 @@ public void Visit(OneTileScannerAmmo ammo) OnMineralScanned(MaterialProbeType.OneTile); } - private Packet BuildScanOneTileResultPacket(Point location) + private Packet BuildScanOneTileResultPacket(SKPointI location) { var packet = new Packet(ZoneCommand.ScanOneTileResult); packet.AppendLong(_module.Eid); //module EID diff --git a/src/Perpetuum/Zones/Terrains/BlockingInfo.cs b/src/Perpetuum/Zones/Terrains/BlockingInfo.cs index 237f4d9..563c994 100644 --- a/src/Perpetuum/Zones/Terrains/BlockingInfo.cs +++ b/src/Perpetuum/Zones/Terrains/BlockingInfo.cs @@ -1,5 +1,3 @@ -using System; - namespace Perpetuum.Zones.Terrains { [Serializable] diff --git a/src/Perpetuum/Zones/Terrains/ITerrain.cs b/src/Perpetuum/Zones/Terrains/ITerrain.cs index 60aff86..dd1df3b 100644 --- a/src/Perpetuum/Zones/Terrains/ITerrain.cs +++ b/src/Perpetuum/Zones/Terrains/ITerrain.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Perpetuum.Zones.Terrains.Materials; using Perpetuum.Zones.Terrains.Materials.Plants; diff --git a/src/Perpetuum/Zones/Terrains/IUpdateableLayer.cs b/src/Perpetuum/Zones/Terrains/IUpdateableLayer.cs index 6984bd7..3ffbb35 100644 --- a/src/Perpetuum/Zones/Terrains/IUpdateableLayer.cs +++ b/src/Perpetuum/Zones/Terrains/IUpdateableLayer.cs @@ -1,5 +1,3 @@ -using System.IO; - namespace Perpetuum.Zones.Terrains { public interface IUpdateableLayer diff --git a/src/Perpetuum/Zones/Terrains/LayerExtensions.cs b/src/Perpetuum/Zones/Terrains/LayerExtensions.cs index f5b01f0..6f4dc74 100644 --- a/src/Perpetuum/Zones/Terrains/LayerExtensions.cs +++ b/src/Perpetuum/Zones/Terrains/LayerExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Drawing; +using SkiaSharp; using System.Numerics; namespace Perpetuum.Zones.Terrains @@ -11,7 +10,7 @@ public static bool IsValidPosition(this ILayer layer, int x, int y) return x >= 0 && x < layer.Width && y >= 0 && y < layer.Height; } - public static T GetValue(this ILayer layer, Point position) + public static T GetValue(this ILayer layer, SKPointI position) { return layer.GetValue(position.X, position.Y); } diff --git a/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/MineralNodeGeneratorBase.cs b/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/MineralNodeGeneratorBase.cs index a3d8805..696ac5c 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/MineralNodeGeneratorBase.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/MineralNodeGeneratorBase.cs @@ -1,11 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using Perpetuum.Units; using Perpetuum.Units.DockingBases; using Perpetuum.Zones.Finders.PositionFinders; using Perpetuum.Zones.Teleporting; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Materials.Minerals.Generators { @@ -34,11 +31,11 @@ public MineralNode Generate(MineralLayer layer) return node; } - private Dictionary NormalizeNoise(Dictionary noise) + private Dictionary NormalizeNoise(Dictionary noise) { var max = noise.Values.Max(); - var result = new Dictionary(); + var result = new Dictionary(); foreach (var kvp in noise) { @@ -48,9 +45,9 @@ private Dictionary NormalizeNoise(Dictionary noise return result; } - protected abstract Dictionary GenerateNoise(Position startPosition); + protected abstract Dictionary GenerateNoise(Position startPosition); - protected bool IsValid(Point location) + protected bool IsValid(SKPointI location) { if (!_zone.Size.Contains(location.X, location.Y)) return false; @@ -77,7 +74,7 @@ protected bool IsValid(Point location) return true; } - private MineralNode CreateMineralNode(MineralLayer layer, Dictionary tiles) + private MineralNode CreateMineralNode(MineralLayer layer, Dictionary tiles) { int minx = int.MaxValue, miny = int.MaxValue, maxx = 0, maxy = 0; @@ -108,7 +105,7 @@ private MineralNode CreateMineralNode(MineralLayer layer, Dictionary().WithinRange2D(location.ToPosition(), dist).Any()) return true; diff --git a/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/RandomWalkMineralNodeGenerator.cs b/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/RandomWalkMineralNodeGenerator.cs index 6e51c14..24960f1 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/RandomWalkMineralNodeGenerator.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Minerals/Generators/RandomWalkMineralNodeGenerator.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Materials.Minerals.Generators { @@ -13,29 +11,29 @@ public RandomWalkMineralNodeGenerator(IZone zone) : base(zone) private int BrushSize { get; set; } - protected override Dictionary GenerateNoise(Position startPosition) + protected override Dictionary GenerateNoise(Position startPosition) { - var closed = new HashSet(); - var tiles = new Dictionary(); + var closed = new HashSet(); + var tiles = new Dictionary(); - var q = new Queue(); + var q = new Queue(); q.Enqueue(startPosition); var i = 0; - while (q.TryDequeue(out Point current) && i < 50000) + while (q.TryDequeue(out SKPointI current) && i < 50000) { i++; foreach (var point in current.FloodFill(IsValid).Take(BrushSize * BrushSize)) { - tiles.AddOrUpdate(point,1,c => c + 1); + tiles.AddOrUpdate(point, 1, c => c + 1); if (tiles.Count >= MaxTiles) return tiles; } - var r = new List(); + var r = new List(); foreach (var np in current.GetNeighbours()) { diff --git a/src/Perpetuum/Zones/Terrains/Materials/Minerals/GravelLayer.cs b/src/Perpetuum/Zones/Terrains/Materials/Minerals/GravelLayer.cs index b8083c0..b4eb58a 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Minerals/GravelLayer.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Minerals/GravelLayer.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; using Perpetuum.IO; -using Perpetuum.Services.EventServices; using Perpetuum.Zones.Terrains.Materials.Minerals.Generators; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Materials.Minerals { @@ -51,9 +47,9 @@ public void Delete(MineralNode node) public List GetAll() { - var bmp = (Bitmap)Image.FromFile(_fileSystem.CreatePath( Path.Combine("layers", "mineral_gravel.0045.png"))); + var bmp = SKBitmap.Decode(_fileSystem.CreatePath(Path.Combine("layers", "mineral_gravel.0045.png"))); - var minerals = new Dictionary(); + var minerals = new Dictionary(); int minx = int.MaxValue, miny = int.MaxValue, maxx = 0, maxy = 0; @@ -63,7 +59,7 @@ public List GetAll() { var c = bmp.GetPixel(x, y); - var b = c.GetBrightness() * 350000; + var b = c.GetLuminance() * 350000; if (b > 0) { @@ -72,7 +68,7 @@ public List GetAll() maxx = Math.Max(maxx, x); maxy = Math.Max(maxy, y); - var point = new Point(x, y); + var point = new SKPointI(x, y); minerals.Add(point, (uint)b); } } diff --git a/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralExtractor.cs b/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralExtractor.cs index 5a09f42..2a79d1a 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralExtractor.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralExtractor.cs @@ -1,14 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Drawing; using Perpetuum.Collections; using Perpetuum.Items; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Materials.Minerals { public class MineralExtractor : MineralLayerVisitor { - private readonly Point _location; + private readonly SKPointI _location; private readonly uint _amount; private readonly MaterialHelper _materialHelper; @@ -16,7 +14,7 @@ public class MineralExtractor : MineralLayerVisitor public List Items => _items; - public MineralExtractor(Point location,uint amount,MaterialHelper materialHelper) + public MineralExtractor(SKPointI location,uint amount,MaterialHelper materialHelper) { _location = location; _amount = amount; @@ -48,10 +46,10 @@ public override void VisitOreLayer(OreLayer layer) private struct MineralDistance : IComparable { - public readonly Point location; + public readonly SKPointI location; private readonly int _sqrDistance; - public MineralDistance(Point location, int sqrDistance) + public MineralDistance(SKPointI location, int sqrDistance) { this.location = location; _sqrDistance = sqrDistance; @@ -79,7 +77,7 @@ public override void VisitLiquidLayer(LiquidLayer layer) continue; var d = _location.SqrDistance(x, y); - pq.Enqueue(new MineralDistance(new Point(x, y), d)); + pq.Enqueue(new MineralDistance(new SKPointI(x, y), d)); } } diff --git a/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralLayer.cs b/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralLayer.cs index 6418ce8..3c29993 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralLayer.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralLayer.cs @@ -1,13 +1,11 @@ -using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Drawing; using Perpetuum.Log; using Perpetuum.Services.EventServices; using Perpetuum.Services.EventServices.EventMessages; using Perpetuum.Timers; using Perpetuum.Zones.Terrains.Materials.Minerals.Actions; using Perpetuum.Zones.Terrains.Materials.Minerals.Generators; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Materials.Minerals { @@ -81,7 +79,7 @@ public void GenerateNewNode() RunAction(new GenerateMineralNode(generator)); } - public List GetNodesWithinRange(Point location, int range) + public List GetNodesWithinRange(SKPointI location, int range) { var area = Area.FromRadius(location.X, location.Y, range); return GetNodesByArea(area); @@ -100,7 +98,7 @@ public List GetNodesByArea(Area area) return nodes; } - public MineralNode GetNearestNode(Point p) + public MineralNode GetNearestNode(SKPointI p) { MineralNode nearestNode = null; var nearestDistSq = double.MaxValue; @@ -199,7 +197,7 @@ private void OnNodeExpired(MineralNode node) } [CanBeNull] - public MineralNode GetNode(Point p) + public MineralNode GetNode(SKPointI p) { MineralNode node; if (!TryGetNode(p, out node)) @@ -208,7 +206,7 @@ public MineralNode GetNode(Point p) return node; } - public bool TryGetNode(Point p, out MineralNode node) + public bool TryGetNode(SKPointI p, out MineralNode node) { return TryGetNode(p.X, p.Y, out node); } @@ -243,7 +241,7 @@ public void WriteLog(string message) Logger.Info($"Mineral ({_configuration.ZoneId}:{Type}) {message}"); } - public bool HasMineral(Point location) + public bool HasMineral(SKPointI location) { var node = GetNode(location); if (node == null) diff --git a/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralNode.cs b/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralNode.cs index 9180150..2291279 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralNode.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Minerals/MineralNode.cs @@ -1,8 +1,7 @@ -using System; using System.Diagnostics; -using System.Drawing; using Perpetuum.Threading; using Perpetuum.Timers; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Materials.Minerals { @@ -86,7 +85,7 @@ private int GetOffset(int x, int y) return offset; } - public bool HasValue(Point p) + public bool HasValue(SKPointI p) { return HasValue(p.X, p.Y); } @@ -97,7 +96,7 @@ public bool HasValue(int x, int y) return v > 0; } - public uint DecreaseValue(Point p, uint value) + public uint DecreaseValue(SKPointI p, uint value) { OnDecrease(); return DecreaseValue(p.X, p.Y, value); @@ -150,7 +149,7 @@ public ulong GetTotalAmount() return sum; } - public uint GetValue(Point p) + public uint GetValue(SKPointI p) { return GetValue(p.X, p.Y); } @@ -166,7 +165,7 @@ public uint GetValue(int x, int y) return value; } - public void SetValue(Point p,uint value) + public void SetValue(SKPointI p,uint value) { SetValue(p.X,p.Y,value); } @@ -212,9 +211,9 @@ public void Update(TimeSpan time) OnUpdated(); } - public Point GetNearestMineralPosition(Point p) + public SKPointI GetNearestMineralPosition(SKPointI p) { - var nearest = Point.Empty; + var nearest = SKPointI.Empty; var nearestDist = int.MaxValue; var offset = 0; @@ -230,7 +229,7 @@ public Point GetNearestMineralPosition(Point p) if (d >= nearestDist) continue; - nearest = new Point(ax,ay); + nearest = new SKPointI(ax,ay); nearestDist = d; } } diff --git a/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs b/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs index dde5a74..5b78283 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs @@ -1,10 +1,6 @@ using Perpetuum.Log; using Perpetuum.Threading.Process; using Perpetuum.Timers; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; namespace Perpetuum.Zones.Terrains.Materials.Plants { @@ -51,7 +47,7 @@ public PlantHandler(IZone zone) : TimeSpan.FromHours(FULL_PLANT_REGEN_PASS / _total_area); _plantsTimer = new IntervalTimer(refreshRate); _natureSleepAmount = refreshRate; - WorkArea = zone.Size.ToArea(); + WorkArea = new Area(0, 0, zone.Size.Width, zone.Size.Height); ScannerMode = PlantScannerMode.Scanner; ResetState(); } diff --git a/src/Perpetuum/Zones/Terrains/PassableMapBuilder.cs b/src/Perpetuum/Zones/Terrains/PassableMapBuilder.cs index 726f5b3..bd4d5a5 100644 --- a/src/Perpetuum/Zones/Terrains/PassableMapBuilder.cs +++ b/src/Perpetuum/Zones/Terrains/PassableMapBuilder.cs @@ -1,7 +1,6 @@ -using System.Collections.Generic; -using System.Drawing; -using Perpetuum.Builders; +using Perpetuum.Builders; using Perpetuum.Log; +using SkiaSharp; namespace Perpetuum.Zones.Terrains { @@ -11,7 +10,7 @@ public class PassableMapBuilder : IBuilder> private readonly SlopeLayer _slopeLayer; private readonly IEnumerable _startPositions; - private Size _size; + private SKSizeI _size; public PassableMapBuilder(ILayer blocksLayer,SlopeLayer slopeLayer,IEnumerable startPositions) { @@ -19,7 +18,7 @@ public PassableMapBuilder(ILayer blocksLayer,SlopeLayer slopeLayer _slopeLayer = slopeLayer; _startPositions = startPositions; - _size = new Size(blocksLayer.Width, blocksLayer.Height); + _size = new SKSizeI(blocksLayer.Width, blocksLayer.Height); } public ILayer Build() diff --git a/src/Perpetuum/Zones/Terrains/Terraforming/Operations/BlurTerraformingOperation.cs b/src/Perpetuum/Zones/Terrains/Terraforming/Operations/BlurTerraformingOperation.cs index a271b2d..93dc720 100644 --- a/src/Perpetuum/Zones/Terrains/Terraforming/Operations/BlurTerraformingOperation.cs +++ b/src/Perpetuum/Zones/Terrains/Terraforming/Operations/BlurTerraformingOperation.cs @@ -1,4 +1,4 @@ -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Terraforming.Operations { @@ -17,7 +17,7 @@ public override void AcceptVisitor(TerraformingOperationVisitor visitor) protected override int ProduceDirection(IZone zone, int x, int y) { - var p = new Point(x, y); + var p = new SKPointI(x, y); var sum = 0.0; foreach (var n in p.GetNeighbours()) diff --git a/src/Perpetuum/Zones/Terrains/Terraforming/TerraformHandler.cs b/src/Perpetuum/Zones/Terrains/Terraforming/TerraformHandler.cs index 3fe7a0a..17220ab 100644 --- a/src/Perpetuum/Zones/Terrains/Terraforming/TerraformHandler.cs +++ b/src/Perpetuum/Zones/Terrains/Terraforming/TerraformHandler.cs @@ -1,13 +1,10 @@ -using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using Perpetuum.ExportedTypes; using Perpetuum.Threading.Process; using Perpetuum.Timers; using Perpetuum.Zones.Beams; using Perpetuum.Zones.Terrains.Terraforming.Operations; +using SkiaSharp; namespace Perpetuum.Zones.Terrains.Terraforming { @@ -152,12 +149,12 @@ private void ProcessAffectedPositions() private void SendAffectedPositions() { - var affectedTiles = new Dictionary(); + var affectedTiles = new Dictionary(); AffectedTile tile; while (_affectedTiles.TryTake(out tile)) { - affectedTiles[new Point(tile.x,tile.y)] = tile.Type; + affectedTiles[new SKPointI(tile.x,tile.y)] = tile.Type; } foreach (var pair in affectedTiles) diff --git a/src/Perpetuum/Zones/Terrains/Terrain.cs b/src/Perpetuum/Zones/Terrains/Terrain.cs index 2debf11..8eb97c8 100644 --- a/src/Perpetuum/Zones/Terrains/Terrain.cs +++ b/src/Perpetuum/Zones/Terrains/Terrain.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Perpetuum.Zones.Terrains.Materials; using Perpetuum.Zones.Terrains.Materials.Plants; diff --git a/src/Perpetuum/Zones/Terrains/TerrainUpdateMonitor.cs b/src/Perpetuum/Zones/Terrains/TerrainUpdateMonitor.cs index 2de367b..1d8ce20 100644 --- a/src/Perpetuum/Zones/Terrains/TerrainUpdateMonitor.cs +++ b/src/Perpetuum/Zones/Terrains/TerrainUpdateMonitor.cs @@ -1,6 +1,5 @@ -using System; using System.Collections.Immutable; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones.Terrains { @@ -8,9 +7,9 @@ public abstract class TerrainUpdateInfo { public LayerType Type { get; } - public Point Position { get; } + public SKPointI Position { get; } - protected TerrainUpdateInfo(LayerType type, Point position) + protected TerrainUpdateInfo(LayerType type, SKPointI position) { Position = position; Type = type; @@ -68,7 +67,7 @@ public override int GetHashCode() public class TileUpdateInfo : TerrainUpdateInfo { - public TileUpdateInfo(LayerType type, Point position) + public TileUpdateInfo(LayerType type, SKPointI position) : base(type, position) { } @@ -178,7 +177,7 @@ private void OnAreaUpdated(LayerType layerType, Area area) private void OnTileUpdated(LayerType layerType, int x, int y) { - var info = new TileUpdateInfo(layerType,new Point(x,y)); + var info = new TileUpdateInfo(layerType, new SKPointI(x,y)); AddUpdateInfo(info); } diff --git a/src/Perpetuum/Zones/Terrains/TerrainUpdateNotifier.cs b/src/Perpetuum/Zones/Terrains/TerrainUpdateNotifier.cs index 55274c9..8001d03 100644 --- a/src/Perpetuum/Zones/Terrains/TerrainUpdateNotifier.cs +++ b/src/Perpetuum/Zones/Terrains/TerrainUpdateNotifier.cs @@ -1,9 +1,5 @@ -using System.Collections.Generic; -using System.Collections.Immutable; +using System.Collections.Immutable; using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Perpetuum.Collections.Spatial; using Perpetuum.Log; using Perpetuum.Players; diff --git a/src/Perpetuum/Zones/Zone.cs b/src/Perpetuum/Zones/Zone.cs index 099e66a..cba2601 100644 --- a/src/Perpetuum/Zones/Zone.cs +++ b/src/Perpetuum/Zones/Zone.cs @@ -31,8 +31,8 @@ using Perpetuum.Zones.ZoneEntityRepositories; using System.Collections.Immutable; using System.Diagnostics; -using System.Drawing; using System.Net.Sockets; +using SkiaSharp; namespace Perpetuum.Zones { @@ -43,7 +43,7 @@ public abstract class Zone : Threading.Process.Process, IZone private ImmutableDictionary _players = ImmutableDictionary.Empty; public int Id => Configuration.Id; - public Size Size => Configuration.Size; + public SKSizeI Size => Configuration.Size; public IDecorHandler DecorHandler { get; set; } diff --git a/src/Perpetuum/Zones/ZoneConfiguration.cs b/src/Perpetuum/Zones/ZoneConfiguration.cs index 7c386dd..7a61b95 100644 --- a/src/Perpetuum/Zones/ZoneConfiguration.cs +++ b/src/Perpetuum/Zones/ZoneConfiguration.cs @@ -2,8 +2,7 @@ using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; using Perpetuum.Zones.Terrains.Materials.Plants; -using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace Perpetuum.Zones { @@ -44,8 +43,8 @@ public IEnumerable GetAll() ZoneConfiguration config = new ZoneConfiguration { Id = id, - WorldPosition = new Point(x, y), - Size = new Size(w, h), + WorldPosition = new SKPointI(x, y), + Size = new SKSizeI(w, h), Name = record.GetValue("name"), Fertility = record.GetValue("fertility"), PluginName = record.GetValue("zoneplugin"), @@ -91,8 +90,8 @@ public sealed class ZoneConfiguration public int plantRuleSetId; public int Id { get; set; } - public Size Size { get; set; } - public Point WorldPosition { get; set; } + public SKSizeI Size { get; set; } + public SKPointI WorldPosition { get; set; } public string PluginName { get; set; } public int Fertility { get; set; } public bool Terraformable { get; set; } diff --git a/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs b/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs index 665f399..d93cabb 100644 --- a/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs +++ b/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs @@ -1,7 +1,6 @@ -using System.Drawing; -using System.Drawing.Imaging; -using Perpetuum.IO; +using Perpetuum.IO; using Perpetuum.Zones.Terrains; +using SkiaSharp; namespace Perpetuum.Zones { @@ -15,10 +14,11 @@ public SaveBitmapHelper(IFileSystem fileSystem) } - public void SaveBitmap(IZone zone,Bitmap bitmap,string name) + public void SaveBitmap(IZone zone, SKBitmap bitmap, string name) { var fn = _fileSystem.CreatePath("bitmaps",zone.CreateTerrainDataFilename(name,"png")); - bitmap.Save(fn,ImageFormat.Png); + using var stream = File.Create(fn); + bitmap.Encode(stream, SKEncodedImageFormat.Png, 100); } } @@ -26,12 +26,17 @@ public void SaveBitmap(IZone zone,Bitmap bitmap,string name) public static partial class ZoneExtensions { - public static Bitmap CreatePassableBitmap(this IZone zone, Color passableTileColor, Color islandTileColor = default(Color)) + public static SKBitmap CreatePassableBitmap(this IZone zone, SKColor passableTileColor, SKColor islandTileColor = default) { - var skipIsland = islandTileColor.Equals(default(Color)); + var skipIsland = islandTileColor.Equals(default); var b = zone.CreateBitmap(); - b.WithGraphics(g => g.FillRectangle(new SolidBrush(Color.FromArgb(255, 0, 0, 0)), 0, 0, zone.Size.Width - 1, zone.Size.Height - 1)); + var canvas = new SKCanvas(b); + + SKPaint paint = new() { Color = SKColors.Black, Style = SKPaintStyle.Fill }; + b.WithCanvas(g => + g.DrawRect(0, 0, zone.Size.Width - 1, zone.Size.Height - 1, paint) + ); return b.ForEach((bmp, x, y) => { @@ -49,10 +54,10 @@ public static partial class ZoneExtensions }); } - public static Bitmap CreateBitmap(this IZone zone) + public static SKBitmap CreateBitmap(this IZone zone) { var size = zone.Size; - return new Bitmap(size.Width,size.Height,PixelFormat.Format32bppArgb); + return new SKBitmap(size.Width, size.Height, SKColorType.Rgba8888, SKAlphaType.Premul); } } diff --git a/src/Perpetuum/Zones/ZoneExtensions.Terrain.cs b/src/Perpetuum/Zones/ZoneExtensions.Terrain.cs index 62a0499..18bd847 100644 --- a/src/Perpetuum/Zones/ZoneExtensions.Terrain.cs +++ b/src/Perpetuum/Zones/ZoneExtensions.Terrain.cs @@ -1,8 +1,6 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using Perpetuum.Data; +using Perpetuum.Data; using Perpetuum.Zones.Terrains; +using SkiaSharp; namespace Perpetuum.Zones { @@ -18,7 +16,7 @@ public static IEnumerable GetPassablePositionFromDb(this IZone zone) .Select(r => new Position(r.GetValue(0), r.GetValue(1))).ToList(); } - public static bool IsWalkableForNpc(this IZone zone,Point position, double slope = MIN_SLOPE) + public static bool IsWalkableForNpc(this IZone zone, SKPointI position, double slope = MIN_SLOPE) { return zone.IsWalkableForNpc(position.X, position.Y, slope); } @@ -36,7 +34,7 @@ public static bool IsWalkable(this IZone zone, int x, int y, double slope = MIN_ return zone.IsWalkable(new Position(x, y), slope); } - public static bool IsWalkable(this IZone zone, Point point, double slope = MIN_SLOPE) + public static bool IsWalkable(this IZone zone, SKPointI point, double slope = MIN_SLOPE) { return zone.IsWalkable(point.ToPosition(),slope); } diff --git a/src/Perpetuum/Zones/ZoneExtensions.cs b/src/Perpetuum/Zones/ZoneExtensions.cs index fe9e047..3620c7c 100644 --- a/src/Perpetuum/Zones/ZoneExtensions.cs +++ b/src/Perpetuum/Zones/ZoneExtensions.cs @@ -7,7 +7,7 @@ using Perpetuum.Units; using Perpetuum.Zones.RemoteControl; using Perpetuum.Zones.Terrains; -using System.Drawing; +using SkiaSharp; using System.Security.Cryptography; namespace Perpetuum.Zones @@ -64,23 +64,23 @@ public void SaveLayerToDisk(IZone zone, ILayer layer) where T : struct public static partial class ZoneExtensions { - public static List FindWalkableArea(this IZone zone, Area area, int size, double slope = 4.0) + public static List FindWalkableArea(this IZone zone, Area area, int size, double slope = 4.0) { area = area.Clamp(zone.Size); while (true) { - Point startPosition; + SKPointI startPosition; while (true) { startPosition = area.GetRandomPosition(); - if (!zone.Terrain.Blocks.GetValue(startPosition).Island && zone.IsWalkable(startPosition, slope)) + if (!zone.Terrain.Blocks.GetValue(startPosition.X, startPosition.Y).Island && zone.IsWalkable(startPosition, slope)) { break; } } - List p = FindWalkableArea(zone, startPosition, area, size, slope); + List p = FindWalkableArea(zone, startPosition, area, size, slope); if (p != null) { return p; @@ -91,14 +91,14 @@ public static List FindWalkableArea(this IZone zone, Area area, int size, } [CanBeNull] - public static List? FindWalkableArea(this IZone zone, Point startPosition, Area area, int size, double slope = 4.0) + public static List? FindWalkableArea(this IZone zone, SKPointI startPosition, Area area, int size, double slope = 4.0) { - Queue q = new(); + Queue q = new(); q.Enqueue(startPosition); - HashSet closed = [startPosition]; + HashSet closed = [startPosition]; - List result = []; - while (q.TryDequeue(out Point position)) + List result = []; + while (q.TryDequeue(out SKPointI position)) { result.Add(position); @@ -108,7 +108,7 @@ public static List FindWalkableArea(this IZone zone, Area area, int size, return result; } - foreach (Point np in position.GetNonDiagonalNeighbours()) + foreach (SKPointI np in position.GetNonDiagonalNeighbours()) { if (closed.Contains(np)) { @@ -138,7 +138,7 @@ public static List FindWalkableArea(this IZone zone, Area area, int size, /// End point of line segment /// Slope capability check for slope-based blocking /// True if tiles checked are walkable - public static bool CheckLinearPath(this IZone zone, Point start, Point end, double slope = 4.0) + public static bool CheckLinearPath(this IZone zone, SKPointI start, SKPointI end, double slope = 4.0) { int x = start.X; int y = start.Y; diff --git a/template/perpetuum.ini b/template/perpetuum.ini.template similarity index 100% rename from template/perpetuum.ini rename to template/perpetuum.ini.template From decdcfd0dec2487c4a663725ea6a4f9b3778bc95 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Fri, 20 Mar 2026 20:21:56 -0400 Subject: [PATCH 07/19] Fix migration order of copy to ensure the generated perpetuum.ini is kept --- script/migration.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/script/migration.sh b/script/migration.sh index d6da288..e62c895 100755 --- a/script/migration.sh +++ b/script/migration.sh @@ -19,6 +19,9 @@ set -eux # - Set initial state using backup # - Run migration for each patch +# Copy the Perpetuum.ServerService data directory +cp -rv /perpetuum-service-data/* /data/ + # Copy the generated perpetuum.ini cp -v /work/perpetuum.ini /data/ @@ -28,8 +31,6 @@ cp -rv /base-data/layers /data/ # Copy the custom-layers to the shared /data/layers cp -rv /custom-layers/* /data/layers -# Copy the Perpetuum.ServerService data directory -cp -rv /perpetuum-service-data/* /data/ runSqlCmd () { set +x From 67f8314330e2698cc1d86b1cc32d8f5a4601f646 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Fri, 20 Mar 2026 20:56:48 -0400 Subject: [PATCH 08/19] Add DefinitionConfig refactor --- .../EntityFramework/DefinitionConfig.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Perpetuum/EntityFramework/DefinitionConfig.cs b/src/Perpetuum/EntityFramework/DefinitionConfig.cs index bfce950..c670491 100644 --- a/src/Perpetuum/EntityFramework/DefinitionConfig.cs +++ b/src/Perpetuum/EntityFramework/DefinitionConfig.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Drawing; +using System.Data; using Perpetuum.Data; using Perpetuum.Log; +using SkiaSharp; namespace Perpetuum.EntityFramework { @@ -51,7 +49,7 @@ public class DefinitionConfig private readonly double _hitSize; - private readonly Color _tint = Color.White; + private readonly SKColor _tint = SKColors.White; private readonly double? _coreCalories; @@ -88,7 +86,7 @@ public int ConstructionRadius get { return (int) constructionRadius.ThrowIfNull(ErrorCodes.ServerError); } } - public Color Tint + public SKColor Tint { get { return _tint; } } @@ -146,7 +144,11 @@ public DefinitionConfig(IDataRecord record) if (!string.IsNullOrEmpty(tint)) { - _tint = ColorTranslator.FromHtml(tint); + bool success = SKColor.TryParse(tint, out _tint); + if (!success) + { + Logger.Info($"Counld not parse tint {_tint}"); + } } } From b31e8210b64d8f24a09c1b153590cd92ca6e8819 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sat, 21 Mar 2026 16:40:13 -0400 Subject: [PATCH 09/19] Update db submodule + migration script to use P34 and P35 full sql files --- db | 2 +- script/migration.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/db b/db index 008632e..049e437 160000 --- a/db +++ b/db @@ -1 +1 @@ -Subproject commit 008632ea4b20af45068e77c469e2ad5a3a4c0253 +Subproject commit 049e4371f1d7279422d4c867ad0d4eee69d7dd3b diff --git a/script/migration.sh b/script/migration.sh index e62c895..36ce383 100755 --- a/script/migration.sh +++ b/script/migration.sh @@ -117,8 +117,8 @@ applyPatch Live_30 live_patch_30.sql Server applyPatch Live_31 live_patch_31.sql Server applyPatch Live_32 live_patch_32.sql Server applyPatch Live_33 live_patch_33.sql Server -applyPatch Live_34 Raw_SQL Server -applyPatch Live_35 Raw_SQL Server +applyPatch Live_34 live_patch_34.sql Server +applyPatch Live_35 live_patch_35.sql Server # Add test account (user: test, pass: test) From 1eba63b2325030202ced5e6995023390e973b9db Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Mon, 23 Mar 2026 21:50:39 -0400 Subject: [PATCH 10/19] Update port mapping to allow more ports for the server to fix black screen issue on client when trying to enter a zone. Now the client seems to work (feature validation is in progress). Disabled EnlistTransaction to ensure DistributedTransactions are disabled --- .env.local | 6 +++--- compose.yml | 2 +- src/Perpetuum/Data/DbQuery.cs | 3 ++- src/Perpetuum/Network/SocketExtensions.cs | 17 ++++++++++++++--- src/Perpetuum/Network/TcpConnection.cs | 4 +++- src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs | 2 +- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/.env.local b/.env.local index 97d026b..833ddaa 100644 --- a/.env.local +++ b/.env.local @@ -13,9 +13,9 @@ DB_PASSWORD="l3(Func execute) if (Transaction.Current != null && connection is DbConnection dbConnection) { - dbConnection.EnlistTransaction(Transaction.Current); + // TODO: Make this disabled only for non-Windows + // dbConnection.EnlistTransaction(Transaction.Current); } IDbCommand command = connection.CreateCommand(); diff --git a/src/Perpetuum/Network/SocketExtensions.cs b/src/Perpetuum/Network/SocketExtensions.cs index 5492835..864ade7 100644 --- a/src/Perpetuum/Network/SocketExtensions.cs +++ b/src/Perpetuum/Network/SocketExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Net.Sockets; +using System.Net.Sockets; using Perpetuum.Log; namespace Perpetuum.Network @@ -9,7 +8,19 @@ public static class SocketExtensions [UsedImplicitly] public static void SetKeepAlive(this Socket socket, bool state, TimeSpan time, TimeSpan interval) { - socket.SetKeepAlive(state, (uint)time.TotalMilliseconds, (uint)interval.TotalMilliseconds); + double keepAliveTime, keepAliveInterval; + if (OperatingSystem.IsWindows()) + { + keepAliveTime = time.TotalMilliseconds; + keepAliveInterval = interval.TotalMilliseconds; + socket.SetKeepAlive(state, (uint)keepAliveTime, (uint)keepAliveInterval); + } + // else + // { + // // Disabled: Not supported by linux + // keepAliveTime = time.Seconds; + // keepAliveInterval = interval.Seconds; + // } } public static void SetKeepAlive(this Socket socket, bool state, uint time, uint interval) diff --git a/src/Perpetuum/Network/TcpConnection.cs b/src/Perpetuum/Network/TcpConnection.cs index c1fcb2e..dbd1be0 100644 --- a/src/Perpetuum/Network/TcpConnection.cs +++ b/src/Perpetuum/Network/TcpConnection.cs @@ -29,7 +29,9 @@ public TcpConnection(Socket socket) _socket.NoDelay = true; _socket.ReceiveBufferSize = RECEIVE_BUFFER_SIZE; _socket.SendBufferSize = SEND_BUFFER_SIZE; - _socket.SetKeepAlive(true, 1000 * 60 * 60 * 24, 5000); + var keepAliveTime = new TimeSpan(24, 0, 0); // 24 hours + var keepAliveInterval = new TimeSpan(0, 0, 5); // 5 seconds + _socket.SetKeepAlive(true, keepAliveTime, keepAliveInterval); RemoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint; } diff --git a/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs b/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs index d93cabb..a69fa76 100644 --- a/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs +++ b/src/Perpetuum/Zones/ZoneExtensions.Bitmap.cs @@ -57,7 +57,7 @@ public static SKBitmap CreatePassableBitmap(this IZone zone, SKColor passableTil public static SKBitmap CreateBitmap(this IZone zone) { var size = zone.Size; - return new SKBitmap(size.Width, size.Height, SKColorType.Rgba8888, SKAlphaType.Premul); + return new SKBitmap(size.Width, size.Height, SKColorType.Rgba8888, SKAlphaType.Opaque); } } From 984ed0a9ac871085d6e7575a02e18e8e39ae68f7 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Mon, 23 Mar 2026 22:53:46 -0400 Subject: [PATCH 11/19] Fix port mapping, defined extra SERVER_PORTS for port range to foreward to the host. --- .env.local | 5 ++++- compose.yml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.env.local b/.env.local index 833ddaa..94b4635 100644 --- a/.env.local +++ b/.env.local @@ -11,9 +11,12 @@ DB_PASSWORD="l3 Date: Tue, 24 Mar 2026 21:26:58 -0400 Subject: [PATCH 12/19] Disable EnlistTransactaction --- src/Perpetuum/Data/DbQuery.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perpetuum/Data/DbQuery.cs b/src/Perpetuum/Data/DbQuery.cs index 2e10aa3..e5b4e6e 100644 --- a/src/Perpetuum/Data/DbQuery.cs +++ b/src/Perpetuum/Data/DbQuery.cs @@ -49,7 +49,7 @@ private T ExecuteHelper(Func execute) if (Transaction.Current != null && connection is DbConnection dbConnection) { - // TODO: Make this disabled only for non-Windows + // TODO: Make this disabled only for non-Windows // dbConnection.EnlistTransaction(Transaction.Current); } From c19dedfd697789be7470c75baccec211859a15e8 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Fri, 27 Mar 2026 21:41:04 -0400 Subject: [PATCH 13/19] Add documentation in the readme for how to setup the containers, make the EnlistTransaction configurable with the DistributedTransactions state --- Makefile | 2 +- README.md | 110 ++++++++++++++++++ .../PerpetuumBootstrapper.cs | 1 + src/Perpetuum/Data/DbQuery.cs | 7 +- src/Perpetuum/GlobalConfiguration.cs | 2 + 5 files changed, 117 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 4722989..239e063 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ stop: down: ./script/compose.sh down -# Stop and delete the containers, also delete the openperpetuum-data volume +# Stop and delete the containers, also delete the volumes (openperpetuum-data, openperpetuum-db) delete: ./script/compose.sh down -v diff --git a/README.md b/README.md index b74c0a2..273c3a3 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,113 @@ # The Open Perpetuum Server 2 +## Setup (container) + +This section explains how to setup for local development using docker/podman compose containers where it can be controlled using some make commands. + +Here is some context for how this works: + +The entry point is `compose.yml` which contains the containers, volumes and network definitions. + +There are 2 volumes: +- `openperpetuum-data`: contains the original `PerpetuumServer/Data` + custom layers + generated perpetuum.ini +- `openperpetuum-db`: contains the database files for persistence + +There is an environment file to control most of the configuration of this setup: +- `.env.local` + +### 0. Requirements +- (optional) make (to help with docker-compose commands) +- docker/podman +- Steam: Perpetuum Dedicated server installed +- Latest gamma islands layers: https://drive.google.com/file/d/1Xp0T1K57Pv-vjgmpXMG8Iea_ec0bWYR4/view?usp=drive_link +- Latest asset resource: https://drive.google.com/file/d/18fh8aRqMP1J7ycGBNGraFyQ31mMXZaq1/view?usp=drive_link + +### 1. Clone this repository and update submodules + +Start by cloning this repository +```sh +git clone https://github.com/OpenPerpetuum/PerpetuumServer2.git +``` +or +```sh +git clone git@github.com:OpenPerpetuum/PerpetuumServer2.git +``` + +Checkout on the develop branch +```sh +git checkout develop +``` + +This repository contains 2 submodules. +- db: (OPDB) database migration files for each game update +- asset: (OPResource) game client resources that are fetched once the client connect to the server. Contains definition files for all game entities, translations, gfx, map data (layers), audio files, custom bot models. + +You can initialize and update them with this command: +```sh +git submodule init && git submodule update +``` + +### 2. Update custom resources + +This section must be performed if there are updates on the gamma layers or asset resource. + +- Uncompress gamma layers into a temporary directory +- Copy gamma layers in `asset/lang0000/layers/GAMMA_LAYERS_NEW` (all .bin files) +- Create `custom-layers` directory +- Copy gamma layers in a new directory `custom-layers` (all .bin files) (the same one as above) +- Unarchive asset resource into a temporary directory +- Copy asset resource into `asset/lang0000` directory (gfx, sfx, textures) +- Create `perpetuum-data` directory +- Copy original PerpetuumServer/data folder into `perpetuum-data` (database, layers) + + +### 3. Run the server + +At this point, you are ready to run the server. + +Note: Take a look at the `.env.local` if you need to see what ports are used, what is the database password, or if you want to update various paths. + +#### 3.1. Start + +```sh +make up +``` + +This will build and start containers. The migration will run. Once the command exit, you might need to wait for a few minutes since the server is starting up. + +You can monitor the server status with this command: +```sh +make log-server +``` + +If you see logs like `Unit enter to zone` or `Planthandler STOP SIGNAL received`, then the server is ready for a client to connect. + +#### 3.2. Setup client with that local server +- Open the client +- Click on `Server list` +- Click on `ADD PRIVATE SERVER` +- Enter Name: `local`, Server address: `127.0.0.1:17700` (update the port to match your `SERVER_PORT` from the `.env.local` file) +- Click `OK` + +#### 3.3. Connect client to the local server +- Select `local` in the server list +- Click `Connect` (this might take a few minutes to load, at this point the asset server is transfering files to the client) +- Login with the test account user: `test`, password: `test` + +#### 3.4 Stop the server +```sh +make down +``` + +This will stop and delete the containers but keep the data and db volumes + +#### 3,5 Stop and delete server data +```sh +make delete +``` + +This will stop and delete all data such as containers and volumes (data, db) + + + diff --git a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs index d3fa67d..24c2bf6 100644 --- a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs +++ b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs @@ -136,6 +136,7 @@ public void Init(string gameRoot, bool distributedTransactions) Logger.Current = _container.Resolve>(); GlobalConfiguration config = _container.Resolve(); + config.DistributedTransactions = distributedTransactions; _container.Resolve().State = HostState.Init; diff --git a/src/Perpetuum/Data/DbQuery.cs b/src/Perpetuum/Data/DbQuery.cs index e5b4e6e..f73b11e 100644 --- a/src/Perpetuum/Data/DbQuery.cs +++ b/src/Perpetuum/Data/DbQuery.cs @@ -6,7 +6,7 @@ namespace Perpetuum.Data { public delegate IDbConnection DbConnectionFactory(); - public class DbQuery(DbConnectionFactory connectionFactory) + public class DbQuery(DbConnectionFactory connectionFactory, GlobalConfiguration configuration) { private readonly DbConnectionFactory _connectionFactory = connectionFactory; @@ -47,10 +47,9 @@ private T ExecuteHelper(Func execute) using IDbConnection connection = _connectionFactory(); connection.Open(); - if (Transaction.Current != null && connection is DbConnection dbConnection) + if (configuration.DistributedTransactions && Transaction.Current != null && connection is DbConnection dbConnection) { - // TODO: Make this disabled only for non-Windows - // dbConnection.EnlistTransaction(Transaction.Current); + dbConnection.EnlistTransaction(Transaction.Current); } IDbCommand command = connection.CreateCommand(); diff --git a/src/Perpetuum/GlobalConfiguration.cs b/src/Perpetuum/GlobalConfiguration.cs index 9fd5157..ab41f0d 100644 --- a/src/Perpetuum/GlobalConfiguration.cs +++ b/src/Perpetuum/GlobalConfiguration.cs @@ -23,6 +23,8 @@ public class GlobalConfiguration public bool EnableDev { get; set; } + public bool DistributedTransactions { get; set; } + public CorporationConfiguration Corporation { get; set; } public bool StartServerInAdminOnlyMode { get; set; } From 17c38fabbdce4d440cfe54976afe17a6e567cafa Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Fri, 27 Mar 2026 22:36:46 -0400 Subject: [PATCH 14/19] Update db image to use mssql-2025 --- compose.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compose.yml b/compose.yml index d08d12a..a11ae35 100644 --- a/compose.yml +++ b/compose.yml @@ -12,8 +12,7 @@ services: - ${ASSET_PORT}:1337 db: - # TODO: update to 2022 - image: mcr.microsoft.com/mssql/server:2019-latest + image: mcr.microsoft.com/mssql/server:2025-latest ports: - ${DB_PORT}:1433 environment: From afe07ea53feea922f25cd07f099ccadc0157e5d5 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sat, 28 Mar 2026 18:37:40 -0400 Subject: [PATCH 15/19] Fix WithCanvas extension to preserve the Bitmap using SKCanvas instead of SKSurface, update usage of canvas.DrawText to fix Y position by taking into account the font size since the origin is on top left instead of bottom left. --- .../Zone/StatsMapDrawing/DrawMissionTargetLog.cs | 4 ++-- .../Zone/StatsMapDrawing/GenerateMissionSpots.cs | 10 +++++----- .../Zone/StatsMapDrawing/WorstMissionSpots.cs | 8 ++++---- .../Zone/StatsMapDrawing/ZoneDrawStatMap.cs | 16 ++++++++-------- src/Perpetuum/BitmapExtensions.cs | 3 +-- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs index ed3fd36..9b80323 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs @@ -117,8 +117,8 @@ private void DrawOneCategory(IRequest request,MissionLocation missionLocation, M var category1 = category; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 15); var paint = new SKPaint { Color = SKColors.White }; - bitmap.WithCanvas(gx => gx.DrawText(category1.ToString(), 20, 40, font, paint)); - bitmap.WithCanvas(gx => gx.DrawText(littleText, 20, 60, font, paint)); + bitmap.WithCanvas(gx => gx.DrawText(category1.ToString(), 20, 40 + font.size, font, paint)); + bitmap.WithCanvas(gx => gx.DrawText(littleText, 20, 60 + font.size, font, paint)); var idString = $"{missionLocation.id:0000}"; diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs index 0ba7d62..c90dc60 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs @@ -273,11 +273,11 @@ private SKBitmap DrawResultOnBitmap(List spotInfos, Dictionary c.DrawText(fttext, 20, 40, font, fieldTerminalColorPaint)); - b.WithCanvas(c => c.DrawText(swtext, 20, 60, font, switchPaint)); - b.WithCanvas(c => c.DrawText(kiotext, 20, 80, font, kioskPaint)); - b.WithCanvas(c => c.DrawText(istext, 20, 100, font, itemSupplyPaint)); - b.WithCanvas(c => c.DrawText(rptext, 20, 120, font, randomPointPaint)); + b.WithCanvas(c => c.DrawText(fttext, 20, 40 + font.size, font, fieldTerminalColorPaint)); + b.WithCanvas(c => c.DrawText(swtext, 20, 60 + font.size, font, switchPaint)); + b.WithCanvas(c => c.DrawText(kiotext, 20, 80 + font.size, font, kioskPaint)); + b.WithCanvas(c => c.DrawText(istext, 20, 100 + font.size, font, itemSupplyPaint)); + b.WithCanvas(c => c.DrawText(rptext, 20, 120 + font.size, font, randomPointPaint)); return b; } diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs index f8d563f..8124cd0 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs @@ -37,10 +37,10 @@ private SKBitmap DrawWorstSpotsMap() var kioskPaint = new SKPaint { Color = _kioskColor }; var itemSupplyPaint = new SKPaint { Color = _itemSupplyColor }; var randomPointPaint = new SKPaint { Color = _randomPointColor }; - b.WithCanvas(c => c.DrawText("switch", 20, 60, font, switchPaint)); - b.WithCanvas(c => c.DrawText("item submit/kiosk", 20, 80, font, kioskPaint)); - b.WithCanvas(c => c.DrawText("item supply", 20, 100, font, itemSupplyPaint)); - b.WithCanvas(c => c.DrawText("random point", 20, 120, font, randomPointPaint)); + b.WithCanvas(c => c.DrawText("switch", 20, 60 + font.size, font, switchPaint)); + b.WithCanvas(c => c.DrawText("item submit/kiosk", 20, 80 + font.size, font, kioskPaint)); + b.WithCanvas(c => c.DrawText("item supply", 20, 100 + font.size, font, itemSupplyPaint)); + b.WithCanvas(c => c.DrawText("random point", 20, 120 + font.size, font, randomPointPaint)); return b; diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs index a3b2f38..cc50013 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs @@ -93,7 +93,7 @@ private void CreateAndSave(string postfix, Func bitmapFactory) var paint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 20); - bmp.WithCanvas(c => c.DrawText(_zone.Configuration.Name, 10, 10, font, paint)); + bmp.WithCanvas(c => c.DrawText(_zone.Configuration.Name, 10, 10 + font.size, font, paint)); string fileName = "stat_" + postfix; if (_sendtoclient) // send to client. @@ -352,7 +352,7 @@ private SKBitmap CreatePlayersMap() c.DrawOval(rect2, pen2); var textPaint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 12); - c.DrawText(unit.Nick, x + 10, y + 10, font, textPaint); + c.DrawText(unit.Nick, x + 10, y + 10 + font.size, font, textPaint); } }); } @@ -374,7 +374,7 @@ private void DrawNpcPresencesOnGraphic(SKCanvas canvas) canvas.DrawRect(presence.Area.X1, presence.Area.Y1, presence.Area.Width, presence.Area.Height, paint); var textPaint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 8); - canvas.DrawText(presence.Configuration.Name, presence.Area.X1, presence.Area.Y1, font, textPaint); + canvas.DrawText(presence.Configuration.Name, presence.Area.X1, presence.Area.Y1 + font.size, font, textPaint); } } @@ -398,7 +398,7 @@ private void DrawNpcFlocksOnGraphic(SKCanvas canvas) canvas.DrawOval(rect2, pen2); var textPaint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 10); - canvas.DrawText(flock.Configuration.Name, txSpawnMax, tySpawnMax, font, textPaint); + canvas.DrawText(flock.Configuration.Name, txSpawnMax, tySpawnMax + font.size, font, textPaint); } } @@ -431,7 +431,7 @@ private void DrawMissionTargetsOnGraphics(SKCanvas canvas) canvas.DrawOval(rect, pen); var textPaint = new SKPaint { Color = SKColors.White }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 8); - canvas.DrawText(targetNames[missionTarget.id], tx, ty, font, textPaint); + canvas.DrawText(targetNames[missionTarget.id], tx, ty + font.size, font, textPaint); } } @@ -762,7 +762,7 @@ private SKBitmap CreateMineralsToNormalizedBitmap(MineralLayer layer) string infoString = $"{layer.Type}"; var paint = new SKPaint { Color = SKColors.White }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 10); - c.DrawText(infoString, 10, 10, font, paint); + c.DrawText(infoString, 10, 10 + font.size, font, paint); }); } @@ -829,7 +829,7 @@ private void CreateTeleportDecorMaps(out SKBitmap? bitmap, out SKBitmap? circles }); var textPaint = new SKPaint { Color = SKColors.White }; - canvas.DrawText(maximumDistance.ToString(CultureInfo.InvariantCulture), (float)td.CurrentPosition.X, (float)td.CurrentPosition.Y, font, textPaint); + canvas.DrawText(maximumDistance.ToString(CultureInfo.InvariantCulture), (float)td.CurrentPosition.X, (float)td.CurrentPosition.Y + font.size, font, textPaint); if (maximumDistance <= 0) { @@ -925,7 +925,7 @@ private void DrawStringTopLeft(SKCanvas canvas, string text) { var paint = new SKPaint { Color = SKColors.Chocolate }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 20); - canvas.DrawText(text, 50, 100, font, paint); + canvas.DrawText(text, 50, 100 + font.size, font, paint); } private void SendDrawFunctionFinished(IRequest request) diff --git a/src/Perpetuum/BitmapExtensions.cs b/src/Perpetuum/BitmapExtensions.cs index 6b6392f..baf5c6a 100644 --- a/src/Perpetuum/BitmapExtensions.cs +++ b/src/Perpetuum/BitmapExtensions.cs @@ -12,9 +12,8 @@ public static class BitmapExtensions return null; } - using (var surface = SKSurface.Create(new SKImageInfo(bitmap.Width, bitmap.Height))) + using (var canvas = new SKCanvas(bitmap)) { - var canvas = surface.Canvas; action(canvas); } From cba0e766ddf65e5c754765de33521f0e1d783d63 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sat, 28 Mar 2026 18:56:16 -0400 Subject: [PATCH 16/19] Fix font.size to use Size property --- .../Zone/StatsMapDrawing/DrawMissionTargetLog.cs | 4 ++-- .../Zone/StatsMapDrawing/GenerateMissionSpots.cs | 10 +++++----- .../Zone/StatsMapDrawing/WorstMissionSpots.cs | 8 ++++---- .../Zone/StatsMapDrawing/ZoneDrawStatMap.cs | 16 ++++++++-------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs index 9b80323..bcb7d85 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/DrawMissionTargetLog.cs @@ -117,8 +117,8 @@ private void DrawOneCategory(IRequest request,MissionLocation missionLocation, M var category1 = category; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 15); var paint = new SKPaint { Color = SKColors.White }; - bitmap.WithCanvas(gx => gx.DrawText(category1.ToString(), 20, 40 + font.size, font, paint)); - bitmap.WithCanvas(gx => gx.DrawText(littleText, 20, 60 + font.size, font, paint)); + bitmap.WithCanvas(gx => gx.DrawText(category1.ToString(), 20, 40 + font.Size, font, paint)); + bitmap.WithCanvas(gx => gx.DrawText(littleText, 20, 60 + font.Size, font, paint)); var idString = $"{missionLocation.id:0000}"; diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs index c90dc60..bbde225 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/GenerateMissionSpots.cs @@ -273,11 +273,11 @@ private SKBitmap DrawResultOnBitmap(List spotInfos, Dictionary c.DrawText(fttext, 20, 40 + font.size, font, fieldTerminalColorPaint)); - b.WithCanvas(c => c.DrawText(swtext, 20, 60 + font.size, font, switchPaint)); - b.WithCanvas(c => c.DrawText(kiotext, 20, 80 + font.size, font, kioskPaint)); - b.WithCanvas(c => c.DrawText(istext, 20, 100 + font.size, font, itemSupplyPaint)); - b.WithCanvas(c => c.DrawText(rptext, 20, 120 + font.size, font, randomPointPaint)); + b.WithCanvas(c => c.DrawText(fttext, 20, 40 + font.Size, font, fieldTerminalColorPaint)); + b.WithCanvas(c => c.DrawText(swtext, 20, 60 + font.Size, font, switchPaint)); + b.WithCanvas(c => c.DrawText(kiotext, 20, 80 + font.Size, font, kioskPaint)); + b.WithCanvas(c => c.DrawText(istext, 20, 100 + font.Size, font, itemSupplyPaint)); + b.WithCanvas(c => c.DrawText(rptext, 20, 120 + font.Size, font, randomPointPaint)); return b; } diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs index 8124cd0..9a86fee 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/WorstMissionSpots.cs @@ -37,10 +37,10 @@ private SKBitmap DrawWorstSpotsMap() var kioskPaint = new SKPaint { Color = _kioskColor }; var itemSupplyPaint = new SKPaint { Color = _itemSupplyColor }; var randomPointPaint = new SKPaint { Color = _randomPointColor }; - b.WithCanvas(c => c.DrawText("switch", 20, 60 + font.size, font, switchPaint)); - b.WithCanvas(c => c.DrawText("item submit/kiosk", 20, 80 + font.size, font, kioskPaint)); - b.WithCanvas(c => c.DrawText("item supply", 20, 100 + font.size, font, itemSupplyPaint)); - b.WithCanvas(c => c.DrawText("random point", 20, 120 + font.size, font, randomPointPaint)); + b.WithCanvas(c => c.DrawText("switch", 20, 60 + font.Size, font, switchPaint)); + b.WithCanvas(c => c.DrawText("item submit/kiosk", 20, 80 + font.Size, font, kioskPaint)); + b.WithCanvas(c => c.DrawText("item supply", 20, 100 + font.Size, font, itemSupplyPaint)); + b.WithCanvas(c => c.DrawText("random point", 20, 120 + font.Size, font, randomPointPaint)); return b; diff --git a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs index cc50013..8929f7e 100644 --- a/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs +++ b/src/Perpetuum.RequestHandlers/Zone/StatsMapDrawing/ZoneDrawStatMap.cs @@ -93,7 +93,7 @@ private void CreateAndSave(string postfix, Func bitmapFactory) var paint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 20); - bmp.WithCanvas(c => c.DrawText(_zone.Configuration.Name, 10, 10 + font.size, font, paint)); + bmp.WithCanvas(c => c.DrawText(_zone.Configuration.Name, 10, 10 + font.Size, font, paint)); string fileName = "stat_" + postfix; if (_sendtoclient) // send to client. @@ -352,7 +352,7 @@ private SKBitmap CreatePlayersMap() c.DrawOval(rect2, pen2); var textPaint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 12); - c.DrawText(unit.Nick, x + 10, y + 10 + font.size, font, textPaint); + c.DrawText(unit.Nick, x + 10, y + 10 + font.Size, font, textPaint); } }); } @@ -374,7 +374,7 @@ private void DrawNpcPresencesOnGraphic(SKCanvas canvas) canvas.DrawRect(presence.Area.X1, presence.Area.Y1, presence.Area.Width, presence.Area.Height, paint); var textPaint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 8); - canvas.DrawText(presence.Configuration.Name, presence.Area.X1, presence.Area.Y1 + font.size, font, textPaint); + canvas.DrawText(presence.Configuration.Name, presence.Area.X1, presence.Area.Y1 + font.Size, font, textPaint); } } @@ -398,7 +398,7 @@ private void DrawNpcFlocksOnGraphic(SKCanvas canvas) canvas.DrawOval(rect2, pen2); var textPaint = new SKPaint { Color = SKColors.Red }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 10); - canvas.DrawText(flock.Configuration.Name, txSpawnMax, tySpawnMax + font.size, font, textPaint); + canvas.DrawText(flock.Configuration.Name, txSpawnMax, tySpawnMax + font.Size, font, textPaint); } } @@ -431,7 +431,7 @@ private void DrawMissionTargetsOnGraphics(SKCanvas canvas) canvas.DrawOval(rect, pen); var textPaint = new SKPaint { Color = SKColors.White }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 8); - canvas.DrawText(targetNames[missionTarget.id], tx, ty + font.size, font, textPaint); + canvas.DrawText(targetNames[missionTarget.id], tx, ty + font.Size, font, textPaint); } } @@ -762,7 +762,7 @@ private SKBitmap CreateMineralsToNormalizedBitmap(MineralLayer layer) string infoString = $"{layer.Type}"; var paint = new SKPaint { Color = SKColors.White }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 10); - c.DrawText(infoString, 10, 10 + font.size, font, paint); + c.DrawText(infoString, 10, 10 + font.Size, font, paint); }); } @@ -829,7 +829,7 @@ private void CreateTeleportDecorMaps(out SKBitmap? bitmap, out SKBitmap? circles }); var textPaint = new SKPaint { Color = SKColors.White }; - canvas.DrawText(maximumDistance.ToString(CultureInfo.InvariantCulture), (float)td.CurrentPosition.X, (float)td.CurrentPosition.Y + font.size, font, textPaint); + canvas.DrawText(maximumDistance.ToString(CultureInfo.InvariantCulture), (float)td.CurrentPosition.X, (float)td.CurrentPosition.Y + font.Size, font, textPaint); if (maximumDistance <= 0) { @@ -925,7 +925,7 @@ private void DrawStringTopLeft(SKCanvas canvas, string text) { var paint = new SKPaint { Color = SKColors.Chocolate }; var font = new SKFont(SKTypeface.FromFamilyName("Tahoma"), 20); - canvas.DrawText(text, 50, 100 + font.size, font, paint); + canvas.DrawText(text, 50, 100 + font.Size, font, paint); } private void SendDrawFunctionFinished(IRequest request) From 8a4061094e55743e3465f640215bac031c516ae9 Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sun, 29 Mar 2026 11:49:59 -0400 Subject: [PATCH 17/19] Fix pixel check to use Alpha instead of the Luminance --- src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs b/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs index 430cd89..4f8d607 100644 --- a/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs +++ b/src/Perpetuum.RequestHandlers/Zone/ZoneSetLayerWithBitMap.cs @@ -27,7 +27,7 @@ public void HandleRequest(IZoneRequest request) { zone.Terrain.Controls.UpdateAll((x, y, c) => { - if (bmp.GetPixel(x, y).GetLuminance() == 0) + if (bmp.GetPixel(x, y).Alpha == 0) { return c; } From 005b8ce8b5c91ec88b9d461836723b0a027080cc Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sun, 29 Mar 2026 17:21:54 -0400 Subject: [PATCH 18/19] Fix typo, replace usage of manual creation of Area with size.ToArea(), update comment --- src/Perpetuum.Server/Program.cs | 2 +- src/Perpetuum/EntityFramework/DefinitionConfig.cs | 2 +- .../Services/Relics/RelicManagers/OutpostRelicManager.cs | 2 +- src/Perpetuum/Services/RiftSystem/RiftManager.cs | 2 +- .../Zones/Artifacts/Generators/PersistentArtifactGenerator.cs | 2 +- .../PositionFinders/RandomWalkableAroundPositionFinder.cs | 2 +- src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs | 2 +- .../Zones/NpcSystem/Presences/PresenceConfiguration.cs | 2 +- src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Perpetuum.Server/Program.cs b/src/Perpetuum.Server/Program.cs index c24f486..d828f3d 100644 --- a/src/Perpetuum.Server/Program.cs +++ b/src/Perpetuum.Server/Program.cs @@ -37,7 +37,7 @@ static int Main(string[] args) return 3; } - // TODO: fix a way to take optional argument to be able to configure the DistributedTransactions from here + // When using PerpetuumServer, the DistributedTransactions is enabled bootstrapper.Init(gameRoot.Value, true); if (bootstrapper.TryInitUpnp(out bool upnpSuccess)) diff --git a/src/Perpetuum/EntityFramework/DefinitionConfig.cs b/src/Perpetuum/EntityFramework/DefinitionConfig.cs index c670491..b28b5ba 100644 --- a/src/Perpetuum/EntityFramework/DefinitionConfig.cs +++ b/src/Perpetuum/EntityFramework/DefinitionConfig.cs @@ -147,7 +147,7 @@ public DefinitionConfig(IDataRecord record) bool success = SKColor.TryParse(tint, out _tint); if (!success) { - Logger.Info($"Counld not parse tint {_tint}"); + Logger.Info($"Could not parse tint {_tint}"); } } } diff --git a/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs b/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs index 89c8135..46b6ccc 100644 --- a/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs +++ b/src/Perpetuum/Services/Relics/RelicManagers/OutpostRelicManager.cs @@ -81,7 +81,7 @@ protected override SKPointI FindRelicPosition(RelicInfo info) var posFinder = new ClosestWalkablePositionFinder(_zone, randomPos); posFinder.Find(out Position p); - var result = _zone.FindWalkableArea(p, new Area(0, 0, _zone.Size.Width, _zone.Size.Height), SPAWN_AREA_REQUIRED_SIZE); + var result = _zone.FindWalkableArea(p, _zone.Size.ToArea(), SPAWN_AREA_REQUIRED_SIZE); if(result != null) { return p; diff --git a/src/Perpetuum/Services/RiftSystem/RiftManager.cs b/src/Perpetuum/Services/RiftSystem/RiftManager.cs index dc90a5a..e717796 100644 --- a/src/Perpetuum/Services/RiftSystem/RiftManager.cs +++ b/src/Perpetuum/Services/RiftSystem/RiftManager.cs @@ -47,7 +47,7 @@ public PvpRiftSpawnPositionFinder(IZone zone) : base(zone) protected override SKPointI FindSpawnPosition(IZone zone) { - var p = zone.FindWalkableArea(new Area(0, 0, zone.Size.Width, zone.Size.Height), 20); + var p = zone.FindWalkableArea(zone.Size.ToArea(), 20); return p.RandomElement(); } } diff --git a/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs b/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs index 82e8f10..7e97015 100644 --- a/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs +++ b/src/Perpetuum/Zones/Artifacts/Generators/PersistentArtifactGenerator.cs @@ -81,7 +81,7 @@ private static SKPointI FindArtifactPosition(IZone zone) } // gamman keresunk teruletet - var p = zone.FindWalkableArea(new Area(0, 0, zone.Size.Width, zone.Size.Height), 20); + var p = zone.FindWalkableArea(zone.Size.ToArea(), 20); return p.RandomElement(); } diff --git a/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs b/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs index cb02c8a..e7f8fe7 100644 --- a/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs +++ b/src/Perpetuum/Zones/Finders/PositionFinders/RandomWalkableAroundPositionFinder.cs @@ -21,7 +21,7 @@ public RandomWalkableAroundPositionFinder(IZone zone, Position origin, int range _slope = slope; _origin = origin; _maxRange = range; - _zoneArea = new Area(0, 0, zone.Size.Width, zone.Size.Height); + _zoneArea = zone.Size.ToArea(); } protected Position FindClosestWalkable(IZone zone, Position pos) diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs b/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs index b57a0d1..1b9809f 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/DynamicPresence.cs @@ -56,7 +56,7 @@ public DynamicPresence(IZone zone, IPresenceConfiguration configuration) : base( public override Area Area { - get { return new Area(0, 0, Zone.Size.Width, Zone.Size.Height); } + get { return Zone.Size.ToArea(); } } protected override void OnPresenceExpired() diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs index 9c78869..3536dda 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs @@ -48,7 +48,7 @@ public class DirectPresenceConfiguration : PresenceConfiguration public DirectPresenceConfiguration(IZone zone) : base(_idGenerator.GetNextID(), PresenceType.Direct) { - Area = new Area(0, 0, zone.Size.Width, zone.Size.Height); + Area = zone.Size.ToArea(); Name = "direct presence " + ID; SpawnId = 10; //dynamic kamubol, szerintem kicsit sem kell Note = "abs! rulez"; diff --git a/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs b/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs index 5b78283..77f9554 100644 --- a/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs +++ b/src/Perpetuum/Zones/Terrains/Materials/Plants/PlantHandler.cs @@ -47,7 +47,7 @@ public PlantHandler(IZone zone) : TimeSpan.FromHours(FULL_PLANT_REGEN_PASS / _total_area); _plantsTimer = new IntervalTimer(refreshRate); _natureSleepAmount = refreshRate; - WorkArea = new Area(0, 0, zone.Size.Width, zone.Size.Height); + WorkArea = zone.Size.ToArea(); ScannerMode = PlantScannerMode.Scanner; ResetState(); } From 14a1e651d58ead01dec7d5b714b18ecf09109a2c Mon Sep 17 00:00:00 2001 From: Philippe Cloutier Date: Sun, 29 Mar 2026 17:24:31 -0400 Subject: [PATCH 19/19] Fix PresenceConfiguration to use the Configuration size instead of the zone size. --- .../Zones/NpcSystem/Presences/PresenceConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs b/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs index 3536dda..b681040 100644 --- a/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs +++ b/src/Perpetuum/Zones/NpcSystem/Presences/PresenceConfiguration.cs @@ -48,7 +48,7 @@ public class DirectPresenceConfiguration : PresenceConfiguration public DirectPresenceConfiguration(IZone zone) : base(_idGenerator.GetNextID(), PresenceType.Direct) { - Area = zone.Size.ToArea(); + Area = zone.Configuration.Size.ToArea(); Name = "direct presence " + ID; SpawnId = 10; //dynamic kamubol, szerintem kicsit sem kell Note = "abs! rulez";