diff --git a/NWN.Anvil/src/main/API/Events/Native/DamageEvents/DamageData.cs b/NWN.Anvil/src/main/API/Events/Native/DamageEvents/DamageData.cs index fa3a501e8..c7c92e8b7 100644 --- a/NWN.Anvil/src/main/API/Events/Native/DamageEvents/DamageData.cs +++ b/NWN.Anvil/src/main/API/Events/Native/DamageEvents/DamageData.cs @@ -110,6 +110,120 @@ public T Sonic set => source[11] = value; } + public T Custom1 + { + get => source[13]; + set => source[13] = value; + } + + public T Custom2 + { + get => source[14]; + set => source[14] = value; + } + + public T Custom3 + { + get => source[15]; + set => source[15] = value; + } + + public T Custom4 + { + get => source[16]; + set => source[16] = value; + } + + public T Custom5 + { + get => source[17]; + set => source[17] = value; + } + + public T Custom6 + { + get => source[18]; + set => source[18] = value; + } + + public T Custom7 + { + get => source[19]; + set => source[19] = value; + } + + public T Custom8 + { + get => source[20]; + set => source[20] = value; + } + + public T Custom9 + { + get => source[21]; + set => source[21] = value; + } + + public T Custom10 + { + get => source[22]; + set => source[22] = value; + } + + public T Custom11 + { + get => source[23]; + set => source[23] = value; + } + + public T Custom12 + { + get => source[24]; + set => source[24] = value; + } + + public T Custom13 + { + get => source[25]; + set => source[25] = value; + } + + public T Custom14 + { + get => source[26]; + set => source[26] = value; + } + + public T Custom15 + { + get => source[27]; + set => source[27] = value; + } + + public T Custom16 + { + get => source[28]; + set => source[28] = value; + } + + public T Custom17 + { + get => source[29]; + set => source[29] = value; + } + + public T Custom18 + { + get => source[30]; + set => source[30] = value; + } + + public T Custom19 + { + get => source[31]; + set => source[31] = value; + } + public T GetDamageByType(DamageType damageType) { int index = BitOperations.Log2((uint)damageType); diff --git a/NWN.Anvil/src/main/API/Events/Native/SpellEvents/OnSpellBroadcast.cs b/NWN.Anvil/src/main/API/Events/Native/SpellEvents/OnSpellBroadcast.cs index 89dd10429..1b44acb5c 100644 --- a/NWN.Anvil/src/main/API/Events/Native/SpellEvents/OnSpellBroadcast.cs +++ b/NWN.Anvil/src/main/API/Events/Native/SpellEvents/OnSpellBroadcast.cs @@ -1,8 +1,10 @@ using System; +using System.Numerics; using System.Runtime.InteropServices; using Anvil.API.Events; using Anvil.Native; using Anvil.Services; +using NWN.Core; using NWN.Native.API; namespace Anvil.API.Events @@ -17,6 +19,8 @@ public sealed class OnSpellBroadcast : IEvent public bool PreventSpellCast { get; set; } public NwSpell Spell { get; private init; } = null!; + public NwGameObject TargetObject { get; private init; } = null!; + public Vector3 TargetPosition { get; private init; } NwObject IEvent.Context => Caster; @@ -36,12 +40,16 @@ private static void OnBroadcastSpellCast(void* pCreature, uint nSpellId, byte nM { CNWSCreature creature = CNWSCreature.FromPointer(pCreature); + NwGameObject oTarget = ((uint)creature.m_pExecutingAIAction.m_pParameter[5]).ToNwObject()!; + OnSpellBroadcast eventData = ProcessEvent(EventCallbackType.Before, new OnSpellBroadcast { Caster = creature.ToNwObject()!, Spell = NwSpell.FromSpellId((int)nSpellId)!, ClassIndex = nMultiClass, Feat = NwFeat.FromFeatId(nFeat)!, + TargetObject = oTarget, + TargetPosition = oTarget is not null ? oTarget.Position : new Vector3(BitConverter.Int32BitsToSingle((int)creature.m_pExecutingAIAction.m_pParameter[6]), BitConverter.Int32BitsToSingle((int)creature.m_pExecutingAIAction.m_pParameter[7]), BitConverter.Int32BitsToSingle((int)creature.m_pExecutingAIAction.m_pParameter[8])), }); if (!eventData.PreventSpellCast) diff --git a/NWN.Anvil/src/main/API/Objects/NwAreaOfEffect.cs b/NWN.Anvil/src/main/API/Objects/NwAreaOfEffect.cs index 99eae71d8..a43b504b7 100644 --- a/NWN.Anvil/src/main/API/Objects/NwAreaOfEffect.cs +++ b/NWN.Anvil/src/main/API/Objects/NwAreaOfEffect.cs @@ -104,5 +104,17 @@ private protected override void AddToArea(CNWSArea area, float x, float y, float { AreaOfEffect.AddToArea(area, x, y, z, true.ToInt()); } + /// + /// Set the radius of this area of effect. + /// + /// The new radius of the area of effect. + public void SetRadius(float radius) + { + if (radius > 0 && AreaOfEffect.m_nShape == 0) + { + AreaOfEffect.SetShape(0, radius); + } + } + } } diff --git a/NWN.Anvil/src/main/API/Objects/NwCreature.cs b/NWN.Anvil/src/main/API/Objects/NwCreature.cs index 7991da289..03d9b78b8 100644 --- a/NWN.Anvil/src/main/API/Objects/NwCreature.cs +++ b/NWN.Anvil/src/main/API/Objects/NwCreature.cs @@ -992,6 +992,33 @@ public async Task ActionCounterspell(NwGameObject counterSpellTarget) await WaitForObjectContext(); NWScript.ActionCounterSpell(counterSpellTarget); } + /// + /// Forces a PC to level up without the level up GUI. + /// + /// The class to level up. + /// The hit points gained during this level up. + /// The abilty to increase : 6 = no increase. + /// Is this an epic level. + /// Number of skill points to give + /// Sets a cleric domain for the class (255 = no domain) + /// Sets the second cleric domain for the class (255 = no domain) + /// Sets the wizard school for the class (255 = no school) + /// Adds the new stats to the character sheet + public void ForceLevelUp(byte nClass, byte nHitDie, byte nAbilityGain = 6, int bEpic = 0, ushort nSkillPointsRemaining = 0, byte nDomain1 = 255, byte nDomain2 = 255, byte nSchool = 255, int addStatsToList = 1) + { + CNWLevelStats stats = new() + { + m_nClass = nClass, + m_nHitDie = nHitDie, + m_nAbilityGain = nAbilityGain, + m_bEpic = bEpic, + m_nSkillPointsRemaining = nSkillPointsRemaining, + }; + + Creature.m_pStats.LevelUp(stats, nDomain1, nDomain2, nSchool, addStatsToList); + GC.SuppressFinalize(stats); + } + /// /// Instructs this creature to equip the specified item into the given inventory slot.