From b7153776596b50bd46cbcb9c99361d57fdbfbb83 Mon Sep 17 00:00:00 2001 From: Jhett Black <10942655+jhett12321@users.noreply.github.com> Date: Wed, 12 Apr 2023 22:14:58 +0200 Subject: [PATCH 1/4] Update changelog. --- CHANGELOG.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e4973854..64c1e5347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,19 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Unreleased -https://github.com/nwn-dotnet/Anvil/compare/v8193.34.26...HEAD +https://github.com/nwn-dotnet/Anvil/compare/v8193.34.27...HEAD ### Added -- NwCreature: Added `BodyBag`, `BodyBagTemplate` properties. -- NwPlaceable: Added `IsBodyBag` property. +- N/A ### Package Updates - N/A ### Changed -- OnPlayerGuiEvent: `EffectIcon` property is now nullable. -- OnDebugPlayVisualEffect: `Effect` property is now nullable. -- APIs that accept a `TableEntry` parameter now have implicit casts (e.g. `EffectIconTableEntry` & `EffectIcon`). +- N/A ### Deprecated - N/A @@ -24,6 +21,21 @@ https://github.com/nwn-dotnet/Anvil/compare/v8193.34.26...HEAD ### Removed - N/A +### Fixed +- N/A + +## 8193.34.27 +https://github.com/nwn-dotnet/Anvil/compare/v8193.34.26...v8193.34.27 + +### Added +- NwCreature: Added `BodyBag`, `BodyBagTemplate` properties. +- NwPlaceable: Added `IsBodyBag` property. + +### Changed +- OnPlayerGuiEvent: `EffectIcon` property is now nullable. +- OnDebugPlayVisualEffect: `Effect` property is now nullable. +- APIs that accept a `TableEntry` parameter now have implicit casts (e.g. `EffectIconTableEntry` & `EffectIcon`). + ### Fixed - NwCreature: Fixed an infinite loop caused by the `Associates` property when having dominated creature associates. - Added some index/range checks for some usages of game table data. From a0a7dd499742a3a33a4613930ddde82894e8127f Mon Sep 17 00:00:00 2001 From: Jhett Black <10942655+jhett12321@users.noreply.github.com> Date: Sat, 15 Apr 2023 00:27:08 +0200 Subject: [PATCH 2/4] Make VirtualMachine API more safe. Fix VM issues (#648) * Allow areas/module as killer for creature OnDeath. * Use current recursion level for resolving script event type. * VirtualMachine: Don't expose valid flag, but determine based on passed in ID. * Match NWNX handler expression for NotHandled script result. * Apply the updated script + event id, don't edit the copy. --- .../CreatureEvents/CreatureEvents.OnDeath.cs | 2 +- .../main/API/Events/Game/GameEventFactory.cs | 2 +- NWN.Anvil/src/main/API/Scripts/CallInfo.cs | 2 +- NWN.Anvil/src/main/API/Utils/VirtualMachine.cs | 17 +++++++++++------ .../ScriptDispatch/ScriptHandleResult.cs | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/NWN.Anvil/src/main/API/Events/Game/CreatureEvents/CreatureEvents.OnDeath.cs b/NWN.Anvil/src/main/API/Events/Game/CreatureEvents/CreatureEvents.OnDeath.cs index bd70642b9..4b9933560 100644 --- a/NWN.Anvil/src/main/API/Events/Game/CreatureEvents/CreatureEvents.OnDeath.cs +++ b/NWN.Anvil/src/main/API/Events/Game/CreatureEvents/CreatureEvents.OnDeath.cs @@ -23,7 +23,7 @@ public sealed class OnDeath : IEvent /// /// Gets the that killed . /// - public NwGameObject Killer { get; } = NWScript.GetLastKiller().ToNwObject()!; + public NwObject? Killer { get; } = NWScript.GetLastKiller().ToNwObject(); NwObject IEvent.Context => KilledCreature; } diff --git a/NWN.Anvil/src/main/API/Events/Game/GameEventFactory.cs b/NWN.Anvil/src/main/API/Events/Game/GameEventFactory.cs index 705862178..af3c79c85 100644 --- a/NWN.Anvil/src/main/API/Events/Game/GameEventFactory.cs +++ b/NWN.Anvil/src/main/API/Events/Game/GameEventFactory.cs @@ -44,7 +44,7 @@ ScriptHandleResult IScriptDispatcher.ExecuteScript(string? scriptName, uint oidS return ScriptHandleResult.NotHandled; } - EventScriptType eventScriptType = (EventScriptType)NWScript.GetCurrentlyRunningEvent(); + EventScriptType eventScriptType = (EventScriptType)NWScript.GetCurrentlyRunningEvent(false.ToInt()); if (eventScriptType == EventScriptType.None) { return ScriptHandleResult.NotHandled; diff --git a/NWN.Anvil/src/main/API/Scripts/CallInfo.cs b/NWN.Anvil/src/main/API/Scripts/CallInfo.cs index acefe33af..e10ca149b 100644 --- a/NWN.Anvil/src/main/API/Scripts/CallInfo.cs +++ b/NWN.Anvil/src/main/API/Scripts/CallInfo.cs @@ -16,7 +16,7 @@ public CallInfo(string scriptName, NwObject? objSelf) { ScriptName = scriptName; ObjectSelf = objSelf; - ScriptType = (EventScriptType)NWScript.GetCurrentlyRunningEvent(); + ScriptType = (EventScriptType)NWScript.GetCurrentlyRunningEvent(false.ToInt()); } /// diff --git a/NWN.Anvil/src/main/API/Utils/VirtualMachine.cs b/NWN.Anvil/src/main/API/Utils/VirtualMachine.cs index 74d8609ee..de5b26065 100644 --- a/NWN.Anvil/src/main/API/Utils/VirtualMachine.cs +++ b/NWN.Anvil/src/main/API/Utils/VirtualMachine.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using Anvil.Internal; using Anvil.Services; using NLog; using NWN.Core; @@ -89,9 +90,9 @@ public void Execute(string scriptName, params (string ParamName, string ParamVal Execute(scriptName, null, scriptParams); } - public void ExecuteInScriptContext(System.Action action, uint objectId = NwObject.Invalid, int scriptEventId = 0, bool valid = false) + public void ExecuteInScriptContext(System.Action action, uint objectId = NwObject.Invalid, int scriptEventId = 0) { - int spBefore = PushScriptContext(objectId, scriptEventId, valid); + int spBefore = PushScriptContext(objectId, scriptEventId); try { action(); @@ -106,9 +107,9 @@ public void ExecuteInScriptContext(System.Action action, uint objectId = NwObjec } } - public T ExecuteInScriptContext(System.Func action, uint objectId = NwObject.Invalid, int scriptEventId = 0, bool valid = false) + public T ExecuteInScriptContext(System.Func action, uint objectId = NwObject.Invalid, int scriptEventId = 0) { - int spBefore = PushScriptContext(objectId, scriptEventId, valid); + int spBefore = PushScriptContext(objectId, scriptEventId); try { @@ -181,9 +182,10 @@ private int PopScriptContext() return virtualMachine.m_cRunTimeStack.GetStackPointer(); } - private int PushScriptContext(uint oid, int scriptEventId, bool valid) + private int PushScriptContext(uint oid, int scriptEventId) { CNWVirtualMachineCommands cmd = CNWVirtualMachineCommands.FromPointer(virtualMachine.m_pCmdImplementer.Pointer); + bool valid = LowLevel.ServerExoApp.GetGameObject(oid) != null; if (virtualMachine.m_nRecursionLevel++ == -1) { @@ -196,7 +198,10 @@ private int PushScriptContext(uint oid, int scriptEventId, bool valid) virtualMachine.m_oidObjectRunScript[virtualMachine.m_nRecursionLevel] = oid; virtualMachine.m_bValidObjectRunScript[virtualMachine.m_nRecursionLevel] = valid.ToInt(); - virtualMachine.m_pVirtualMachineScript[virtualMachine.m_nRecursionLevel].m_nScriptEventID = scriptEventId; + CVirtualMachineScript script = virtualMachine.m_pVirtualMachineScript[virtualMachine.m_nRecursionLevel]; + script.m_nScriptEventID = scriptEventId; + + virtualMachine.m_pVirtualMachineScript[virtualMachine.m_nRecursionLevel] = script; cmd.m_oidObjectRunScript = virtualMachine.m_oidObjectRunScript[virtualMachine.m_nRecursionLevel]; cmd.m_bValidObjectRunScript = virtualMachine.m_bValidObjectRunScript[virtualMachine.m_nRecursionLevel]; diff --git a/NWN.Anvil/src/main/Services/ScriptDispatch/ScriptHandleResult.cs b/NWN.Anvil/src/main/Services/ScriptDispatch/ScriptHandleResult.cs index cc1d11f31..5f6787fed 100644 --- a/NWN.Anvil/src/main/Services/ScriptDispatch/ScriptHandleResult.cs +++ b/NWN.Anvil/src/main/Services/ScriptDispatch/ScriptHandleResult.cs @@ -2,7 +2,7 @@ namespace Anvil.Services { public enum ScriptHandleResult { - NotHandled = -1, + NotHandled = ~0, Handled = 0, False = 0, True = 1, From 010fe474be193c306c686a8b4be0334d468a6223 Mon Sep 17 00:00:00 2001 From: Jhett Black <10942655+jhett12321@users.noreply.github.com> Date: Sat, 15 Apr 2023 00:27:20 +0200 Subject: [PATCH 3/4] GetAssociate is 1-indexed, not 0. (#649) --- NWN.Anvil/src/main/API/Objects/NwCreature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NWN.Anvil/src/main/API/Objects/NwCreature.cs b/NWN.Anvil/src/main/API/Objects/NwCreature.cs index 0cdf78bf2..278eccd8b 100644 --- a/NWN.Anvil/src/main/API/Objects/NwCreature.cs +++ b/NWN.Anvil/src/main/API/Objects/NwCreature.cs @@ -2548,7 +2548,7 @@ private List GetAssociates(AssociateType associateType) List associates = new List(); int type = (int)associateType; - for (int i = 0;; i++) + for (int i = 1;; i++) { NwCreature? associate = NWScript.GetAssociate(type, this, i).ToNwObject(); if (associate == null || associates.Contains(associate)) From 65dedbb7417e2511b3badf1af91fdc0b08fc2cab Mon Sep 17 00:00:00 2001 From: Jhett Black <10942655+jhett12321@users.noreply.github.com> Date: Tue, 18 Apr 2023 23:44:45 +0200 Subject: [PATCH 4/4] Update changelog. --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64c1e5347..e8a40d03e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,10 @@ https://github.com/nwn-dotnet/Anvil/compare/v8193.34.27...HEAD - N/A ### Fixed -- N/A +- NwCreature: Fixed an issue where GetAssociates would return an empty list for certain associate types. +- VirtualMachine: Fix an issue where the context object would be incorrectly flagged as invalid. +- Creature.OnDeath: Support Area/Module as the killer of the creature. +- EventService: More reliable handling of game events. ## 8193.34.27 https://github.com/nwn-dotnet/Anvil/compare/v8193.34.26...v8193.34.27