| 1 | namespace NewMoon.Samples.NPC; |
| 2 | |
| 3 | /// <summary> |
| 4 | /// An example gamemode that registers one custom NPC entity, <c>npc_bot_newmoon</c>, which fronts <c>base_boss</c>. |
| 5 | /// </summary> |
| 6 | [GameMode("Custom NPC Sample", "custom-npc-sample", Description = "Registers a custom NPC entity as an example.")] |
| 7 | public sealed partial class CustomNpcSample : FGamePlugin |
| 8 | { |
| 9 | /// <inheritdoc/> |
| 10 | protected override void OnPluginStart() |
| 11 | { |
| 12 | // The logger is set first: adoption inside the registration can raise OnSpawn for NPCs that already exist. |
| 13 | NPCBotNewMoon.Log = PLogger; |
| 14 | PLogger.LogRegistered(RegisterCustomEntities(NewMoon.Generated.CustomEntityTable.All)); |
| 15 | } |
| 16 | |
| 17 | /// <inheritdoc/> |
| 18 | protected override void OnPluginEnd() => PLogger.LogEnded(); |
| 19 | } |
| 20 |
screwdriver / gist:f99d5bf9d8f14fe2a9a3bf56d4ac0c66
Last active 12 minutes ago
| 1 | using JetBrains.Annotations; |
| 2 | using Microsoft.Extensions.Logging; |
| 3 | |
| 4 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member |
| 5 | |
| 6 | namespace NewMoon.Samples.NPC; |
| 7 | |
| 8 | /// <summary> |
| 9 | /// Source-generated log messages. |
| 10 | /// </summary> |
| 11 | [UsedImplicitly] |
| 12 | public static partial class CustomNPCSampleLogger |
| 13 | { |
| 14 | [LoggerMessage(1, LogLevel.Information, "Custom NPC sample registered {Count} custom entity classes")] |
| 15 | public static partial void LogRegistered(this ILogger logger, int count); |
| 16 | |
| 17 | [LoggerMessage(2, LogLevel.Information, "Custom NPC sample ended: OnPluginEnd ran before the scope released")] |
| 18 | public static partial void LogEnded(this ILogger logger); |
| 19 | |
| 20 | [LoggerMessage(3, LogLevel.Information, "npc_bot_newmoon OnSpawn {Index}")] |
| 21 | public static partial void LogNPCSpawn(this ILogger logger, int index); |
| 22 | |
| 23 | [LoggerMessage(4, LogLevel.Information, "npc_bot_newmoon OnActivate {Index}")] |
| 24 | public static partial void LogNPCActivate(this ILogger logger, int index); |
| 25 | |
| 26 | [LoggerMessage(5, LogLevel.Information, "npc_bot_newmoon OnRemoved {Index}")] |
| 27 | public static partial void LogNPCRemoved(this ILogger logger, int index); |
| 28 | } |
| 29 |
| 1 | using Microsoft.Extensions.Logging; |
| 2 | |
| 3 | namespace NewMoon.Samples.NPC; |
| 4 | |
| 5 | /// <summary> |
| 6 | /// The custom NPC: a <c>npc_bot_newmoon</c> classname that is a factory alias of <c>base_boss</c>. Spawning it yields a real |
| 7 | /// <c>base_boss</c> that carries the new classname, and the registry calls the lifecycle overrides below. |
| 8 | /// </summary> |
| 9 | /// <remarks> |
| 10 | /// The class only logs. Reading keyvalues, inputs and outputs from a custom entity is not part of the landed API yet, so the |
| 11 | /// spawner supplies <c>health</c> and <c>model</c>, for example <c>ent_create npc_bot_newmoon health 500 model models/bots/headless_hatman.mdl</c>. The registry needs an accessible parameterless constructor. |
| 12 | /// </remarks> |
| 13 | [CustomEntity("npc_bot_newmoon", "base_boss", PrecacheModels = ["models/bots/headless_hatman.mdl"])] |
| 14 | internal sealed class NPCBotNewMoon : FCustomEntity |
| 15 | { |
| 16 | /// <summary> |
| 17 | /// The logger the callbacks write to; set by <see cref="CustomNpcSample"/> at start-up, because the registry creates this |
| 18 | /// object through its parameterless constructor. |
| 19 | /// </summary> |
| 20 | internal static ILogger? Log { get; set; } |
| 21 | |
| 22 | // Captured at spawn so the remove log never depends on the view still resolving while the instance is torn down. |
| 23 | private int _index = -1; |
| 24 | |
| 25 | /// <inheritdoc/> |
| 26 | protected override void OnSpawn() |
| 27 | { |
| 28 | _index = Entity.Index; |
| 29 | Log?.LogNPCSpawn(_index); |
| 30 | } |
| 31 | |
| 32 | /// <inheritdoc/> |
| 33 | protected override void OnActivate() => Log?.LogNPCActivate(_index); |
| 34 | |
| 35 | /// <inheritdoc/> |
| 36 | protected override void OnRemoved() => Log?.LogNPCRemoved(_index); |
| 37 | } |
| 38 |