Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
jhett12321 committed Apr 12, 2023
2 parents 54aa4e5 + a80e763 commit bdde90b
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 50 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ 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/).

## 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.

## 8193.34.26
https://github.com/nwn-dotnet/Anvil/compare/v8193.34.25...v8193.34.26

Expand Down
42 changes: 4 additions & 38 deletions NWN.Anvil/src/main/API/EngineStructures/ItemProperty.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using NWN.Core;
using NWN.Native.API;

Expand All @@ -17,19 +18,7 @@ internal ItemProperty(CGameEffect effect, bool memoryOwn) : base(effect, memoryO
/// <summary>
/// Gets the cost table used by this item property.
/// </summary>
public TwoDimArray<ItemPropertyCostTableEntry>? CostTable
{
get
{
int tableIndex = Effect.GetInteger(2);
if (tableIndex >= 0 && tableIndex < NwGameTables.ItemPropertyCostTables.Count)
{
return NwGameTables.ItemPropertyCostTables[tableIndex].Table;
}

return null;
}
}
public TwoDimArray<ItemPropertyCostTableEntry>? CostTable => NwGameTables.ItemPropertyCostTables.ElementAtOrDefault(Effect.GetInteger(2))?.Table;

/// <summary>
/// Gets or sets the cost table entry that is set for this item property.<br/>
Expand Down Expand Up @@ -62,19 +51,7 @@ public EffectDuration DurationType
/// <summary>
/// Gets the #1 param table used by this item property.
/// </summary>
public TwoDimArray<ItemPropertyParamTableEntry>? Param1Table
{
get
{
int tableIndex = Effect.GetInteger(4);
if (tableIndex >= 0 && tableIndex < NwGameTables.ItemPropertyParamTables.Count)
{
return NwGameTables.ItemPropertyParamTables[tableIndex].Table;
}

return null;
}
}
public TwoDimArray<ItemPropertyParamTableEntry>? Param1Table => NwGameTables.ItemPropertyParamTables.ElementAtOrDefault(Effect.GetInteger(4))?.Table;

/// <summary>
/// Gets or sets the #1 param table entry that is set for this item property.<br/>
Expand Down Expand Up @@ -119,18 +96,7 @@ public ItemPropertyParamTableEntry? Param1TableValue
/// </summary>
public ItemPropertySubTypeTableEntry? SubType
{
get
{
int tableIndex = Effect.GetInteger(1);
TwoDimArray<ItemPropertySubTypeTableEntry>? table = Property.SubTypeTable;

if (tableIndex >= 0 && table != null && tableIndex < table.Count)
{
return table[tableIndex];
}

return null;
}
get => Property.SubTypeTable?.ElementAtOrDefault(Effect.GetInteger(1));
set => Effect.SetInteger(1, value?.RowIndex ?? -1);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using Anvil.API.Events;
using NWN.Core;

Expand All @@ -25,7 +26,7 @@ public sealed class OnPlayerGuiEvent : IEvent
/// <summary>
/// Gets the effect icon that was selected. Only valid in <see cref="GuiEventType.EffectIconClick"/> events.
/// </summary>
public EffectIconTableEntry EffectIcon => NwGameTables.EffectIconTable[integerEventData];
public EffectIconTableEntry? EffectIcon => NwGameTables.EffectIconTable.ElementAtOrDefault(integerEventData);

/// <summary>
/// Gets the object data associated with this GUI event.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using Anvil.Services;
Expand Down Expand Up @@ -120,7 +121,7 @@ private static OnDebugPlayVisualEffect HandleVisualEffectEvent(CNWSMessage messa
{
Player = player,
TargetObject = target.ToNwObject(),
Effect = NwGameTables.VisualEffectTable[visualEffect],
Effect = NwGameTables.VisualEffectTable.ElementAtOrDefault(visualEffect),
Duration = TimeSpan.FromSeconds(duration),
TargetPosition = position,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public sealed class OnDebugPlayVisualEffect : IEvent
/// <summary>
/// Gets the effect that is attempting to be played.
/// </summary>
public VisualEffectTableEntry Effect { get; internal init; } = null!;
public VisualEffectTableEntry? Effect { get; internal init; }

/// <summary>
/// Gets the player attempting to spawn the visual effect.
Expand Down
33 changes: 27 additions & 6 deletions NWN.Anvil/src/main/API/Objects/NwCreature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ internal CNWSCreature Creature
internal NwCreature(CNWSCreature creature) : base(creature)
{
this.creature = creature;
faction = new NwFaction(creature.GetFaction());
faction = new NwFaction(Creature.GetFaction());
Inventory = new Inventory(this, Creature.m_pcItemRepository);
}

Expand Down Expand Up @@ -197,6 +197,20 @@ public byte BaseShieldArcaneSpellFailure
set => Creature.m_pStats.m_nBaseShieldArcaneSpellFailure = value;
}

/// <summary>
/// Gets the body bag assigned to this creature as a result of its death.
/// </summary>
public NwPlaceable? BodyBag => Creature.m_oidBodyBag.ToNwObject<NwPlaceable>();

/// <summary>
/// Gets or sets the body bag template to use when this creature dies.
/// </summary>
public BodyBagTableEntry BodyBagTemplate
{
get => NwGameTables.BodyBagTable[Creature.m_nBodyBag];
set => Creature.m_nBodyBag = (byte)value.RowIndex;
}

/// <summary>
/// Gets or sets the calculated challenge rating for this creature.
/// </summary>
Expand Down Expand Up @@ -2529,16 +2543,23 @@ private async Task DoActionUnlockObject(NwGameObject target)
NWScript.ActionUnlockObject(target);
}

private IEnumerable<NwCreature> GetAssociates(AssociateType associateType)
private List<NwCreature> GetAssociates(AssociateType associateType)
{
int i;
uint current;
List<NwCreature> associates = new List<NwCreature>();
int type = (int)associateType;

for (i = 1, current = NWScript.GetAssociate(type, this, i); current != Invalid; i++, current = NWScript.GetAssociate(type, this, i))
for (int i = 0;; i++)
{
yield return current.ToNwObject<NwCreature>()!;
NwCreature? associate = NWScript.GetAssociate(type, this, i).ToNwObject<NwCreature>();
if (associate == null || associates.Contains(associate))
{
break;
}

associates.Add(associate);
}

return associates;
}

private PlayerQuickBarButton InternalGetQuickBarButton(byte index)
Expand Down
5 changes: 5 additions & 0 deletions NWN.Anvil/src/main/API/Objects/NwPlaceable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public bool Illumination
/// </summary>
public Inventory Inventory { get; }

/// <summary>
/// Gets if this is a body bag placeable, spawned from a creature's death.
/// </summary>
public bool IsBodyBag => placeable.m_bIsBodyBag.ToBool();

public bool IsStatic
{
get => Placeable.m_bStaticObject.ToBool();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Anvil.API
{
/// <summary>
Expand Down Expand Up @@ -115,5 +117,10 @@ void ITwoDimArrayEntry.InterpretEntry(TwoDimArrayEntry entry)
BodyBag = entry.GetTableEntry("BODY_BAG", NwGameTables.BodyBagTable);
Targetable = entry.GetBool("TARGETABLE");
}

public static implicit operator AppearanceTableEntry?(AppearanceType appearanceType)
{
return NwGameTables.AppearanceTable.ElementAtOrDefault((int)appearanceType);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Anvil.API
{
/// <summary>
Expand Down Expand Up @@ -28,5 +30,10 @@ public void InterpretEntry(TwoDimArrayEntry entry)
Icon = entry.GetString("Icon");
StrRef = entry.GetStrRef("StrRef");
}

public static implicit operator EffectIconTableEntry?(EffectIcon effectIcon)
{
return NwGameTables.EffectIconTable.ElementAtOrDefault((int)effectIcon);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Anvil.API
{
public sealed class ItemPropertyTableEntry : ITwoDimArrayEntry
Expand Down Expand Up @@ -53,7 +55,7 @@ public sealed class ItemPropertyTableEntry : ITwoDimArrayEntry

void ITwoDimArrayEntry.InterpretEntry(TwoDimArrayEntry entry)
{
ItemMap = NwGameTables.ItemPropertyItemMapTable.GetRow(RowIndex);
ItemMap = NwGameTables.ItemPropertyItemMapTable.ElementAtOrDefault(RowIndex);
Name = entry.GetStrRef("Name");
Label = entry.GetString("Label");
SubTypeTable = entry.GetTable<ItemPropertySubTypeTableEntry>("SubTypeResRef");
Expand All @@ -63,5 +65,10 @@ void ITwoDimArrayEntry.InterpretEntry(TwoDimArrayEntry entry)
GameStrRef = entry.GetStrRef("GameStrRef");
Description = entry.GetStrRef("Description");
}

public static implicit operator ItemPropertyTableEntry?(ItemPropertyType propertyType)
{
return NwGameTables.ItemPropertyTable.ElementAtOrDefault((int)propertyType);
}
}
}
4 changes: 3 additions & 1 deletion NWN.Anvil/src/main/API/TwoDimArray/Tables/PartsTableEntry.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Anvil.API
{
public sealed class PartsTableEntry : ITwoDimArrayEntry
Expand All @@ -14,7 +16,7 @@ public void InterpretEntry(TwoDimArrayEntry entry)
{
CostModifier = entry.GetInt("COSTMODIFIER");
ACBonus = entry.GetFloat("ACBONUS");
ArmorTableEntry = ACBonus.HasValue ? NwGameTables.ArmorTable[(int)ACBonus.Value] : null;
ArmorTableEntry = ACBonus.HasValue ? NwGameTables.ArmorTable.ElementAtOrDefault((int)ACBonus.Value) : null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Anvil.API
{
public sealed class ProgrammedEffectTableEntry : ITwoDimArrayEntry
Expand Down Expand Up @@ -43,5 +45,10 @@ public void InterpretEntry(TwoDimArrayEntry entry)
intParamValues[i] = entry.GetInt(columnName);
}
}

public static implicit operator ProgrammedEffectTableEntry?(ProgFxType fxType)
{
return NwGameTables.ProgrammedEffectTable.ElementAtOrDefault((int)fxType);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Anvil.API
{
public sealed class VisualEffectTableEntry : ITwoDimArrayEntry
Expand Down Expand Up @@ -88,5 +90,10 @@ void ITwoDimArrayEntry.InterpretEntry(TwoDimArrayEntry entry)
LowQualityVariant = entry.GetString("LowQuality");
OrientWithObject = entry.GetBool("OrientWithObject");
}

public static implicit operator VisualEffectTableEntry?(VfxType vfxType)
{
return NwGameTables.VisualEffectTable.ElementAtOrDefault((int)vfxType);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Anvil.API;
using NLog;
using NWN.Native.API;
Expand Down Expand Up @@ -36,7 +37,7 @@ public void ClearDamageLevelOverride(NwCreature creature)
InternalVariableInt damageLevelOverride = InternalVariables.DamageLevelOverride(creature);
if (damageLevelOverride.HasValue)
{
return NwGameTables.DamageLevelTable[damageLevelOverride.Value];
return NwGameTables.DamageLevelTable.ElementAtOrDefault(damageLevelOverride.Value);
}

return null;
Expand Down

0 comments on commit bdde90b

Please sign in to comment.