diff --git a/.gitignore b/.gitignore index 69005a1..481723e 100644 --- a/.gitignore +++ b/.gitignore @@ -17,15 +17,8 @@ obj/ **/[Pp]roject.lock.json project.assets.json -## Keep Loreline DLL -!lib/Loreline.dll -!lib/Loreline.xml -!lib/Loreline.deps.json -lib/Loreline/ -lib/loreline-csharp.zip -lib/Loreline.csproj -lib/Loreline.sln -lib/Directory.Build.props +## Loreline (downloaded by init.ps1) +lib/ ## Build results [Dd]ebug/ diff --git a/init.ps1 b/init.ps1 new file mode 100644 index 0000000..5c96afc --- /dev/null +++ b/init.ps1 @@ -0,0 +1,119 @@ +# Open The Box - Initialization Script +# Run this after cloning to download dependencies and verify the environment. +# +# Usage: .\init.ps1 + +$ErrorActionPreference = "Stop" + +$LorelineVersion = "0.7.1" +$LorelineZipUrl = "https://github.com/Loreline/loreline/releases/download/v$LorelineVersion/loreline-csharp.zip" +$LibDir = Join-Path $PSScriptRoot "lib" +$LorelineDll = Join-Path $LibDir "Loreline.dll" +$TempZip = Join-Path $LibDir "loreline-csharp.zip" + +Write-Host "========================================" -ForegroundColor Cyan +Write-Host " Open The Box - Project Setup" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "" + +# ── Step 1: Check .NET SDK ──────────────────────────────────────────── + +Write-Host "[1/3] Checking .NET SDK..." -ForegroundColor Yellow + +$sdks = & dotnet --list-sdks 2>$null +$hasNet10 = $sdks | Where-Object { $_ -match "^10\." } + +if (-not $hasNet10) { + Write-Host " .NET 10 SDK not found." -ForegroundColor Red + Write-Host " Install it with: winget install Microsoft.DotNet.SDK.10" -ForegroundColor Red + Write-Host " Or download from: https://dotnet.microsoft.com/download/dotnet/10.0" -ForegroundColor Red + Write-Host "" + $response = Read-Host " Attempt to install via winget? (y/N)" + if ($response -eq "y" -or $response -eq "Y") { + Write-Host " Installing .NET 10 SDK..." -ForegroundColor Yellow + winget install Microsoft.DotNet.SDK.10 --accept-source-agreements --accept-package-agreements + Write-Host " Installed. You may need to restart your terminal for PATH changes." -ForegroundColor Green + } else { + Write-Host " Skipping .NET 10 SDK install. Build may fail without it." -ForegroundColor Red + } +} else { + $version = ($hasNet10 | Select-Object -First 1) -replace '\s+\[.*$', '' + Write-Host " .NET SDK $version found." -ForegroundColor Green +} + +Write-Host "" + +# ── Step 2: Download Loreline ───────────────────────────────────────── + +Write-Host "[2/3] Checking Loreline dependency..." -ForegroundColor Yellow + +if (-not (Test-Path $LibDir)) { + New-Item -ItemType Directory -Path $LibDir -Force | Out-Null +} + +if (Test-Path $LorelineDll) { + Write-Host " Loreline.dll already present." -ForegroundColor Green +} else { + Write-Host " Downloading Loreline v$LorelineVersion from GitHub..." -ForegroundColor Yellow + try { + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + Invoke-WebRequest -Uri $LorelineZipUrl -OutFile $TempZip -UseBasicParsing + + Write-Host " Extracting..." -ForegroundColor Yellow + $extractDir = Join-Path $LibDir "_loreline_extract" + Expand-Archive -Path $TempZip -DestinationPath $extractDir -Force + + # Find and copy the DLL, XML, and deps.json + $dllSource = Get-ChildItem -Path $extractDir -Recurse -Filter "Loreline.dll" | Select-Object -First 1 + if ($dllSource) { + $sourceDir = $dllSource.DirectoryName + Copy-Item (Join-Path $sourceDir "Loreline.dll") $LibDir -Force + $xmlFile = Join-Path $sourceDir "Loreline.xml" + if (Test-Path $xmlFile) { Copy-Item $xmlFile $LibDir -Force } + $depsFile = Join-Path $sourceDir "Loreline.deps.json" + if (Test-Path $depsFile) { Copy-Item $depsFile $LibDir -Force } + Write-Host " Loreline v$LorelineVersion installed." -ForegroundColor Green + } else { + Write-Host " ERROR: Could not find Loreline.dll in downloaded archive." -ForegroundColor Red + exit 1 + } + + # Cleanup + Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item $TempZip -Force -ErrorAction SilentlyContinue + } + catch { + Write-Host " ERROR: Failed to download Loreline." -ForegroundColor Red + Write-Host " $($_.Exception.Message)" -ForegroundColor Red + Write-Host "" + Write-Host " Manual install:" -ForegroundColor Yellow + Write-Host " 1. Download from: $LorelineZipUrl" -ForegroundColor Yellow + Write-Host " 2. Extract Loreline.dll to: $LibDir" -ForegroundColor Yellow + exit 1 + } +} + +Write-Host "" + +# ── Step 3: Restore NuGet packages ─────────────────────────────────── + +Write-Host "[3/3] Restoring NuGet packages..." -ForegroundColor Yellow +dotnet restore +if ($LASTEXITCODE -eq 0) { + Write-Host " Packages restored." -ForegroundColor Green +} else { + Write-Host " WARNING: Package restore failed. Try running 'dotnet restore' manually." -ForegroundColor Red +} + +Write-Host "" + +# ── Done ────────────────────────────────────────────────────────────── + +Write-Host "========================================" -ForegroundColor Green +Write-Host " Setup complete!" -ForegroundColor Green +Write-Host "========================================" -ForegroundColor Green +Write-Host "" +Write-Host " To build: dotnet build" -ForegroundColor Cyan +Write-Host " To run: dotnet run --project src/OpenTheBox" -ForegroundColor Cyan +Write-Host "" diff --git a/lib/Loreline.deps.json b/lib/Loreline.deps.json deleted file mode 100644 index 5b5cecd..0000000 --- a/lib/Loreline.deps.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETStandard,Version=v2.1/", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETStandard,Version=v2.1": {}, - ".NETStandard,Version=v2.1/": { - "Loreline/1.0.0": { - "runtime": { - "Loreline.dll": {} - } - } - } - }, - "libraries": { - "Loreline/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - } - } -} \ No newline at end of file diff --git a/lib/Loreline.dll b/lib/Loreline.dll deleted file mode 100644 index 21fa97a..0000000 Binary files a/lib/Loreline.dll and /dev/null differ diff --git a/lib/Loreline.xml b/lib/Loreline.xml deleted file mode 100644 index 8e43142..0000000 --- a/lib/Loreline.xml +++ /dev/null @@ -1,495 +0,0 @@ - - - - Loreline - - - - - Base interface to hold loreline values. - This interface allows to map loreline object fields to game-specific objects. - - - - - Called when the object has been created from an interpreter - - The interpreter instance - - - - Get the value associated to the given field key - - The interpreter instance - The field key - The value associated with the key - - - - Set the value associated to the given field key - - The interpreter instance - The field key - The value to set - - - - Remove the field associated to the given key - - The interpreter instance - The field key to remove - True if the key was found and removed, false otherwise - - - - Check if a value exists for the given key - - The interpreter instance - The field key to check - True if the key exists, false otherwise - - - - Get all the fields of this object - - The interpreter instance - An array of field keys - - - - Main interpreter class for Loreline scripts. - This class is responsible for executing a parsed Loreline script, - managing the runtime state, and interacting with the host application - through handler functions. - - - - - Represents a tag in text content, which can be used for styling or other purposes. - - - - - Whether this is a closing tag. - - - - - The value or name of the tag. - - - - - The offset in the text where this tag appears. - - - - - Represents a choice option presented to the user. - - - - - The text of the choice option. - - - - - Any tags associated with the choice text. - - - - - Whether this choice option is currently enabled. - - - - - Delegate type for functions that can be called from the script. - - The interpreter instance - Arguments passed to the function - The result of the function - - - - Callback type for dialogue continuation. - - - - - Contains information about a dialogue to be displayed to the user. - - - - - The interpreter instance. - - - - - The character speaking (null for narrator text). - - - - - The text content to display. - - - - - Any tags in the text. - - - - - Function to call when the text has been displayed. - - - - - Handler type for text output with callback. - This is called when the script needs to display text to the user. - - A Dialogue structure containing all necessary information - - - - Callback type for choice selection. - - The index of the selected choice - - - - Contains information about choices to be presented to the user. - - - - - The interpreter instance. - - - - - The available choice options. - - - - - Function to call with the index of the selected choice. - - - - - Handler type for choice presentation with callback. - This is called when the script needs to present choices to the user. - - A Choice structure containing all necessary information - - - - A custom instanciator to create fields objects. - - The interpreter related to this object creation - The expected type of the object, if there is any known - The associated node in the script, if any - - - - - Contains information about the script execution completion. - - - - - The interpreter instance. - - - - - Retrieve default interpreter options - - - - - Optional map of additional functions to make available to the script - - - - - Tells whether access is strict or not. If set to true, - trying to read or write an undefined variable will throw an error. - - - - - A custom instantiator to create fields objects. - - - - - Optional translations map for localization. - Built from a parsed translation file using Engine.ExtractTranslations(). - - - - - Handler type to be called when the execution finishes. - - A Finish structure containing the interpreter instance - - - - The underlying runtime interpreter instance. - - - - - Creates a new Loreline script interpreter. - - The parsed script to execute - Function to call when displaying dialogue text - Function to call when presenting choices - Function to call when execution finishes - - - - Creates a new Loreline script interpreter. - - The parsed script to execute - Function to call when displaying dialogue text - Function to call when presenting choices - Function to call when execution finishes - Additional options - - - - Starts script execution from the beginning or a specific beat. - - Optional name of the beat to start from. If null, execution starts from - the first beat or a beat named "_" if it exists. - Thrown if the specified beat doesn't exist or if no beats are found in the script - - - - Saves the current state of the interpreter. - This includes all state variables, character states, and execution stack, - allowing execution to be resumed later from the exact same point. - - A JSON string containing the serialized state - - - - Restores the interpreter state from a previously saved state. - This allows resuming execution from a previously saved state. - - The JSON string containing the serialized state - Thrown if the save data version is incompatible - - - - Resumes execution after restoring state. - This should be called after Restore() to continue execution. - - - - - Gets a character by name. - - The name of the character to get - The character's fields or null if the character doesn't exist - - - - Gets a specific field of a character. - - The name of the character - The name of the field to get - The field value or null if the character or field doesn't exist - - - - The main public API for Loreline runtime. - Provides easy access to the core functionality for parsing and running Loreline scripts. - - - - - Parses the given text input and creates an executable instance from it. - - - This is the first step in working with a Loreline script. The returned - object can then be passed to methods Play() or Resume(). - - The Loreline script content as a string (.lor format) - (optional) The file path of the input being parsed. If provided, requires `handleFile` as well. - (optional) A file handler to read imports. If that handler is asynchronous, then `parse()` method will return null and `callback` argument should be used to get the final script - If provided, will be called with the resulting script as argument. Mostly useful when reading file imports asynchronously - The parsed script as an AST instance (if loaded synchronously) - Thrown if the script contains syntax errors or other parsing issues - - - - Starts playing a Loreline script from the beginning or a specific beat. - - - This function takes care of initializing the interpreter and starting execution - immediately. You'll need to provide handlers for dialogues, choices, and - script completion. - - The parsed script (result from ) - Function called when dialogue text should be displayed - Function called when player needs to make a choice - Function called when script execution completes - Name of a specific beat to start from (defaults to first beat) - The interpreter instance that is running the script - - - - Starts playing a Loreline script from the beginning or a specific beat. - - - This function takes care of initializing the interpreter and starting execution - immediately. You'll need to provide handlers for dialogues, choices, and - script completion. - - The parsed script (result from ) - Function called when dialogue text should be displayed - Function called when player needs to make a choice - Function called when script execution completes - Additional options - The interpreter instance that is running the script - - - - Starts playing a Loreline script from the beginning or a specific beat. - - - This function takes care of initializing the interpreter and starting execution - immediately. You'll need to provide handlers for dialogues, choices, and - script completion. - - The parsed script (result from ) - Function called when dialogue text should be displayed - Function called when player needs to make a choice - Function called when script execution completes - Name of a specific beat to start from (defaults to first beat) - Additional options - The interpreter instance that is running the script - - - - Resumes a previously saved Loreline script from its saved state. - - - This allows you to continue a story from the exact point where it was saved, - restoring all state variables, choices, and player progress. - - The parsed script (result from ) - Function called when dialogue text should be displayed - Function called when player needs to make a choice - Function called when script execution completes - The saved game data (typically from ) - Optional beat name to override where to resume from - The interpreter instance that is running the script - - - - Resumes a previously saved Loreline script from its saved state. - - - This allows you to continue a story from the exact point where it was saved, - restoring all state variables, choices, and player progress. - - The parsed script (result from ) - Function called when dialogue text should be displayed - Function called when player needs to make a choice - Function called when script execution completes - The saved game data (typically from ) - Additional options - The interpreter instance that is running the script - - - - Resumes a previously saved Loreline script from its saved state. - - - This allows you to continue a story from the exact point where it was saved, - restoring all state variables, choices, and player progress. - - The parsed script (result from ) - Function called when dialogue text should be displayed - Function called when player needs to make a choice - Function called when script execution completes - The saved game data (typically from ) - Optional beat name to override where to resume from - Additional options - The interpreter instance that is running the script - - - - Extracts translations from a parsed translation script. - - - Given a translation file parsed with , this returns a translations map - that can be passed as to - Play() or Resume(). - - The parsed translation script (result from on a .XX.lor file) - A translations object to pass as - - - - Prints a parsed script back into Loreline source code. - - The parsed script (result from ) - The indentation string to use (defaults to two spaces) - The newline string to use (defaults to "\n") - The printed source code as a string - - - - Represents a node in a Loreline AST. - - - - - The underlying runtime node instance. - - - - - The type of the node as string - - - - - The id of this node (should be unique within a single script hierarchy) - - - - - Converts the node to a JSON representation. - This can be used for debugging or serialization purposes. - - Whether to format the JSON with indentation and line breaks - A JSON string representation of the node - - - - Represents the root node of a Loreline script AST. - - - - - The underlying runtime script instance. - - - - - Creates a new Script instance with the provided runtime script. - - The parsed runtime script to wrap - - -