diff --git a/.agent.md b/.agent.md new file mode 100644 index 0000000..0c262e8 --- /dev/null +++ b/.agent.md @@ -0,0 +1,127 @@ +--- +name: DocWorker +description: Write and improve SampSharp feature documentation articles following DocFX and xref best practices +--- + +# DocWorker Agent + +You are an expert technical writer specializing in SampSharp documentation. Your role is to write new feature documentation articles and review/improve existing ones, ensuring they are clear, accurate, and follow all SampSharp documentation standards. + +## Core Responsibilities + +- Write conceptual documentation articles explaining **what** and **why**, not just showing code +- Create concise, focused examples that illustrate key concepts +- Ensure all articles follow DocFX Markdown formatting and xref conventions +- Review and improve existing articles for clarity, accuracy, and consistency +- Maintain structural consistency across all documentation + +## Documentation Standards + +### YAML Frontmatter + +Every article must have a unique `uid`: + +```yaml +--- +title: Article Title +uid: article-unique-id +--- +``` + +### Cross-References (xref) + +- **Always** use the `` syntax (preferred) for cross-references +- Example: `` or `` +- Use markdown link text syntax `[Text](xref:uid)` only when custom text differs from the page title +- Never use relative links; always use xref for maintainability + +### Code Examples + +- **Inject services** directly into event handler parameters, not constructors +- **Combine examples** for clarity; avoid "show and tell" with separate code blocks +- Use the `[Event]` attribute for event handlers, never `[EventHandler]` +- Keep examples minimal and focused on the concept being explained +- For full lists of available items, refer to the appropriate article with xref + +### DocFX Features + +Use these DocFX Markdown features for rich documentation: + +**Alerts** for important information: + +``` +> [!NOTE] +> Information the user should notice. + +> [!IMPORTANT] +> Essential information. +``` + +**Code snippets** with language specification: + +``` +[!code-csharp[](file.cs#L1-L10)] +``` + +**Includes** for content reuse when appropriate + +### Article Structure + +- **No summary sections** at the end (not recommended for documentation) +- Start with a clear introduction explaining what the article covers +- Use numbered sections for logical flow +- Include API reference xref links where appropriate +- End with cross-references to related articles + +## Key Patterns from SampSharp + +When writing SampSharp articles, remember: + +- **Services are injected into event parameters**, not stored as fields + + ```csharp + [Event] + public void OnGameModeInit(IWorldService worldService) + { + // Use service directly + } + ``` + +- **Component types** are the main interaction points + - `Vehicle` component for vehicle manipulation + - `GlobalObject` component for world objects (named to avoid collision with System.Object) + - `Player` component for player interactions + +- **Events drive gameplay** - explain available events and how to handle them + - Always reference for the full list + - Show realistic event handler examples + +- **Entity creation** happens through IWorldService + - Demonstrate in the `OnGameModeInit` event handler + - Inject IWorldService as a parameter + +## When to Use This Agent + +Invoke this agent when: + +- Writing new SampSharp feature documentation articles +- Reviewing and improving existing SampSharp documentation +- Ensuring documentation follows all DocFX and xref standards +- Need guidance on documentation structure and best practices for SampSharp + +Use the default Copilot agent for general code questions or non-SampSharp tasks. + +## Tool Preferences + +**Preferred tools:** + +- `read_file` - Review existing documentation structure +- `replace_string_in_file` / `multi_replace_string_in_file` - Edit documentation +- `file_search` - Find related articles for xref references +- `grep_search` - Search within specific files for context + +**Avoid:** + +- Source code references in documentation (use framework documentation instead) +- Linking to specific line numbers in source code +- Creating unnecessary summary sections diff --git a/docs/features/commands.md b/docs/features/command-system.md similarity index 99% rename from docs/features/commands.md rename to docs/features/command-system.md index 46f2f52..0dd8780 100644 --- a/docs/features/commands.md +++ b/docs/features/command-system.md @@ -1,9 +1,9 @@ --- -title: Implementing Commands +title: Command System uid: commands --- -# Implementing Commands +# Command System The SampSharp command system provides a declarative way to handle player and console commands through attributes. Commands are discovered automatically from implementations and can include complex features like overloading, aliasing, command groups, and permission checking. diff --git a/docs/features/objects.md b/docs/features/objects.md new file mode 100644 index 0000000..58b4341 --- /dev/null +++ b/docs/features/objects.md @@ -0,0 +1,74 @@ +--- +title: Objects +uid: objects +--- + +# Objects + +Objects are static or dynamic entities in the world that can be created, positioned, and manipulated at runtime. SampSharp distinguishes between global objects (visible to all players) and player objects (visible only to a specific player). + +## Creating Objects + +To create a global object visible to all players, use : + +```csharp +[Event] +public void OnGameModeInit(IWorldService worldService) +{ + var obj = worldService.CreateObject( + modelId: 18631, // object model ID + position: new Vector3(100, 200, 30), // position + rotation: new Vector3(0, 0, 45), // rotation + drawDistance: 300 // draw distance + ); +} +``` + +The returned component is of type (named as such because `Object` is reserved for `System.Object`). + +See for all available parameters. + +## Player Objects + +Player objects are only visible to a specific player, making them useful for personalized or player-specific world elements. Create player objects using : + +```csharp +[Event] +public void OnPlayerSpawn(Player player, IWorldService worldService) +{ + var playerObj = worldService.CreatePlayerObject( + player, + modelId: 18631, + position: new Vector3(100, 200, 30), + rotation: new Vector3(0, 0, 45) + ); +} +``` + +Only the specified player can see and interact with this object. + +## Handling Object Events + +You can respond to object-related events, such as when an object is moved. For example: + +```csharp +[Event] +public void OnObjectMoved(GlobalObject obj) +{ + // Handle object movement +} +``` + +See for a full list of available object events. + +## Manipulating Objects + +The component provides properties and methods to interact with objects. You can change their position, rotation, and other properties: + +```csharp +obj.Position = new Vector3(150, 250, 35); // Change position +obj.Rotation = new Vector3(0, 0, 90); // Change rotation +``` + +See for the full API. + diff --git a/docs/features/timers.md b/docs/features/timers.md index 9c3b303..6bf72bd 100644 --- a/docs/features/timers.md +++ b/docs/features/timers.md @@ -5,17 +5,112 @@ uid: timers # Timers and Scheduling -> [!NOTE] -> This article is coming soon! Check back later, or feel free to open an issue if you have questions. - - +Timers allow you to schedule tasks to execute at regular intervals or after a specific delay. SampSharp provides two approaches: the `[Timer]` attribute for simple repeating timers, and `ITimerService` for more advanced scenarios requiring manual control. + +## Simple Timers with [Timer] Attribute + +The simplest way to create a repeating timer is using the `[Timer]` attribute on a method in your system. Specify the interval in milliseconds: + +```csharp +public class GameSystem : ISystem +{ + [Timer(1000)] // Interval in milliseconds (1 second) + public void OnGameTick() + { + Console.WriteLine("Game tick!"); + } + + [Timer(100)] // 10 times per second + public void OnFastUpdate() + { + // High-frequency updates + } +} +``` + +The timer automatically starts when the system is initialized and runs at the specified interval. This approach is ideal for fire-and-forget timers without manual lifecycle management. + +## Advanced Timer Control with ITimerService + +For more complex scenarios, use `ITimerService` to have full control over timer creation, stopping, and lifecycle. Both `Start` and `Delay` return a `TimerReference` that you can use to cancel the timer: + +```csharp +[Event] +public void OnGameModeInit(ITimerService timerService) +{ + // Repeating timer: runs every 1 second + var repeatTimer = timerService.Start(serviceProvider => + { + Console.WriteLine("Timer tick!"); + }, TimeSpan.FromSeconds(1)); + + // One-time timer: runs once after 5 seconds + var delayTimer = timerService.Delay(serviceProvider => + { + Console.WriteLine("Delayed action executed"); + }, TimeSpan.FromSeconds(5)); +} +``` + +### Canceling Timers + +To stop a running timer, pass its `TimerReference` to `timerService.Stop()`: + +```csharp +public class MySystem : ISystem +{ + private TimerReference? _timer; + + [Event] + public void OnGameModeInit(ITimerService timerService) + { + _timer = timerService.Start(serviceProvider => + { + Console.WriteLine("Timer is running"); + }, TimeSpan.FromSeconds(2)); + } + + public void StopTimer(ITimerService timerService) + { + if (_timer != null) + { + timerService.Stop(_timer); + _timer = null; + } + } +} +``` + +You can also check a timer's state using `TimerReference.IsActive` and `TimerReference.NextTick` to see when the next execution is scheduled. + +### Accessing Services in Timer Actions + +Timer actions receive an `IServiceProvider` parameter, allowing you to access services without storing them as fields: + +```csharp +timerService.Start(serviceProvider => +{ + var worldService = serviceProvider.GetRequiredService(); + // Use worldService within the timer action +}, TimeSpan.FromSeconds(1)); +``` + +This is useful for keeping timers self-contained without field dependencies. + +### One-Time Delays + +Use `Delay` for one-time scheduled tasks without keeping references: + +```csharp +timerService.Delay(serviceProvider => +{ + Console.WriteLine("This runs once after a delay"); +}, TimeSpan.FromSeconds(10)); +``` + +## When to Use Each Approach + +- **[Timer] attribute** — Simple, recurring timers with fixed intervals; fire-and-forget +- **ITimerService** — Manual control needed; dynamic intervals; one-time delays; conditional stopping + +See for the complete API. diff --git a/docs/features/vehicles.md b/docs/features/vehicles.md index 82da5b9..4b04395 100644 --- a/docs/features/vehicles.md +++ b/docs/features/vehicles.md @@ -1,18 +1,86 @@ --- -title: Vehicle Management +title: Vehicles uid: vehicles --- -# Vehicle Management +# Vehicles + +Vehicles are dynamic entities in SampSharp that can be created, configured, and controlled at runtime. This article covers how to spawn vehicles, handle vehicle-related events, and manipulate vehicles using the `Vehicle` component. + +## Spawning a Vehicle + +To create (spawn) a vehicle in the world, use the `IWorldService.CreateVehicle` method. This method allows you to specify the vehicle model, position, rotation, colors, respawn delay, and more. + +**Example: Spawning a vehicle** + +```csharp +public void OnGameModeInit(IWorldService worldService) +{ + var vehicle = worldService.CreateVehicle( + VehicleModelType.Infernus, + new Vector3(1500, -1500, 14), // position + 90f, // rotation (degrees) + color1: 1, // primary color + color2: 1 // secondary color + ); +} +``` + +See for all available parameters. + +## Handling Vehicle Events + +You can respond to vehicle-related events such as when a vehicle spawns, a player enters or exits a vehicle, and more. Here are some common event handlers: + +```csharp +public class VehicleEventSystem : ISystem +{ + [EventHandler] + public void OnVehicleSpawn(Vehicle vehicle) + { + Console.WriteLine($"Vehicle spawned: {vehicle.Model}"); + } + + [EventHandler] + public void OnPlayerEnterVehicle(Player player, Vehicle vehicle, bool isPassenger) + { + Console.WriteLine($"{player} entered vehicle {vehicle.Model}"); + } + + [EventHandler] + public void OnPlayerExitVehicle(Player player, Vehicle vehicle) + { + Console.WriteLine($"{player} exited vehicle {vehicle.Model}"); + } +} +``` + +For a full list of available vehicle events, see . + +## Manipulating Vehicles + +The `Vehicle` component provides many properties and methods to interact with vehicles. Here are some simple examples: + +```csharp +// Set the vehicle's health +vehicle.Health = 1000f; + +// Change the vehicle's color +vehicle.Colors = (3, 6); // primary: 3, secondary: 6 + +// Set the vehicle's velocity +vehicle.Velocity = new Vector3(0, 10, 0); // move forward + +// Turn on the engine +vehicle.Engine = true; + +// Check if the vehicle has a trailer +if (vehicle.HasTrailer) +{ + Console.WriteLine("This vehicle has a trailer attached."); +} +``` + +See for all available properties and methods. -> [!NOTE] -> This article is coming soon! Check back later, or feel free to open an issue if you have questions. -