Skip to content

Commit 241e419

Browse files
feat: random drops (#2486)
* feat: random drops * silent rename quantity * remove extra spaces * added notifiable drop logic to the npc editor * change selected index on add * added notifiable drop logic to the resource editor --------- Co-authored-by: Robbie Lodico <pandacoder@pm.me>
1 parent f391d19 commit 241e419

File tree

11 files changed

+2980
-2883
lines changed

11 files changed

+2980
-2883
lines changed
Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
1+
using Newtonsoft.Json;
2+
13
namespace Intersect.GameObjects;
24

35
public partial class Drop
46
{
7+
private int _maxQuantity;
8+
59
public double Chance { get; set; }
610

711
public Guid ItemId { get; set; }
812

9-
public int Quantity { get; set; }
10-
}
13+
[JsonProperty]
14+
[Obsolete(message: $"Use {nameof(MinQuantity)} instead, the Quantity property will be removed in 0.9-beta", error: true)]
15+
private int Quantity
16+
{
17+
/* Setter only [JsonProperty] annotated private property to "silently" rename Quantity to MinQuantity */
18+
set => MinQuantity = value;
19+
}
20+
21+
/* By renaming Quantity to MinQuantity the "automatic" range given an original "Quantity" value of 3 will be 3 to 3, instead of 1 to 3 or 0 to 3 */
22+
public int MinQuantity { get; set; } = 1;
23+
24+
public int MaxQuantity
25+
{
26+
/* Special getter ensures that MaxQuantity can never be less than MinQuantity, and it doesn't need a non-zero default value as a result */
27+
get => Math.Max(_maxQuantity, MinQuantity);
28+
set => _maxQuantity = value;
29+
}
30+
}

Intersect.Editor/Forms/Editors/frmNpc.Designer.cs

Lines changed: 1766 additions & 1835 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Intersect.Editor/Forms/Editors/frmNpc.cs

Lines changed: 78 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.ComponentModel;
12
using System.Drawing.Imaging;
23
using DarkUI.Forms;
34
using Intersect.Editor.Content;
@@ -13,17 +14,18 @@
1314

1415
namespace Intersect.Editor.Forms.Editors;
1516

16-
1717
public partial class FrmNpc : EditorForm
1818
{
1919

20-
private List<NpcBase> mChanged = new List<NpcBase>();
20+
private List<NpcBase> mChanged = [];
2121

2222
private string mCopiedItem;
2323

2424
private NpcBase mEditorItem;
2525

26-
private List<string> mKnownFolders = new List<string>();
26+
private List<string> mKnownFolders = [];
27+
28+
private BindingList<NotifiableDrop> _dropList = [];
2729

2830
public FrmNpc()
2931
{
@@ -112,6 +114,9 @@ private void frmNpc_Load(object sender, EventArgs e)
112114
cmbScalingStat.Items.Add(Globals.GetStatName(x));
113115
}
114116

117+
lstDrops.DataSource = _dropList;
118+
lstDrops.DisplayMember = nameof(NotifiableDrop.DisplayName);
119+
115120
nudStr.Maximum = Options.Instance.Player.MaxStat;
116121
nudMag.Maximum = Options.Instance.Player.MaxStat;
117122
nudDef.Maximum = Options.Instance.Player.MaxStat;
@@ -211,7 +216,8 @@ private void InitLocalization()
211216

212217
grpDrops.Text = Strings.NpcEditor.drops;
213218
lblDropItem.Text = Strings.NpcEditor.dropitem;
214-
lblDropAmount.Text = Strings.NpcEditor.dropamount;
219+
lblDropMaxAmount.Text = Strings.NpcEditor.DropMaxAmount;
220+
lblDropMinAmount.Text = Strings.NpcEditor.DropMinAmount;
215221
lblDropChance.Text = Strings.NpcEditor.dropchance;
216222
btnDropAdd.Text = Strings.NpcEditor.dropadd;
217223
btnDropRemove.Text = Strings.NpcEditor.dropremove;
@@ -426,40 +432,18 @@ private void DrawNpcSprite()
426432
picNpc.BackgroundImage = picSpriteBmp;
427433
}
428434

429-
private void UpdateDropValues(bool keepIndex = false)
435+
private void UpdateDropValues()
430436
{
431-
var index = lstDrops.SelectedIndex;
432-
lstDrops.Items.Clear();
433-
434-
var drops = mEditorItem.Drops.ToArray();
435-
foreach (var drop in drops)
437+
_dropList.Clear();
438+
foreach (var drop in mEditorItem.Drops)
436439
{
437-
if (ItemBase.Get(drop.ItemId) == null)
440+
_dropList.Add(new NotifiableDrop
438441
{
439-
mEditorItem.Drops.Remove(drop);
440-
}
441-
}
442-
443-
for (var i = 0; i < mEditorItem.Drops.Count; i++)
444-
{
445-
if (mEditorItem.Drops[i].ItemId != Guid.Empty)
446-
{
447-
lstDrops.Items.Add(
448-
Strings.NpcEditor.dropdisplay.ToString(
449-
ItemBase.GetName(mEditorItem.Drops[i].ItemId), mEditorItem.Drops[i].Quantity,
450-
mEditorItem.Drops[i].Chance
451-
)
452-
);
453-
}
454-
else
455-
{
456-
lstDrops.Items.Add(TextUtils.None);
457-
}
458-
}
459-
460-
if (keepIndex && index < lstDrops.Items.Count)
461-
{
462-
lstDrops.SelectedIndex = index;
442+
ItemId = drop.ItemId,
443+
MinQuantity = drop.MinQuantity,
444+
MaxQuantity = drop.MaxQuantity,
445+
Chance = drop.Chance
446+
});
463447
}
464448
}
465449

@@ -724,71 +708,98 @@ private void nudExp_ValueChanged(object sender, EventArgs e)
724708
mEditorItem.Experience = (int)nudExp.Value;
725709
}
726710

711+
private void lstDrops_SelectedIndexChanged(object sender, EventArgs e)
712+
{
713+
if (lstDrops.SelectedIndex > -1)
714+
{
715+
cmbDropItem.SelectedIndex = ItemBase.ListIndex(mEditorItem.Drops[lstDrops.SelectedIndex].ItemId) + 1;
716+
nudDropMaxAmount.Value = mEditorItem.Drops[lstDrops.SelectedIndex].MaxQuantity;
717+
nudDropMinAmount.Value = mEditorItem.Drops[lstDrops.SelectedIndex].MinQuantity;
718+
nudDropChance.Value = (decimal)mEditorItem.Drops[lstDrops.SelectedIndex].Chance;
719+
}
720+
}
721+
727722
private void cmbDropItem_SelectedIndexChanged(object sender, EventArgs e)
728723
{
729-
if (lstDrops.SelectedIndex > -1 && lstDrops.SelectedIndex < mEditorItem.Drops.Count)
724+
int index = lstDrops.SelectedIndex;
725+
if (index < 0 || index > lstDrops.Items.Count)
730726
{
731-
mEditorItem.Drops[lstDrops.SelectedIndex].ItemId = ItemBase.IdFromList(cmbDropItem.SelectedIndex - 1);
727+
return;
732728
}
733729

734-
UpdateDropValues(true);
730+
mEditorItem.Drops[index].ItemId = ItemBase.IdFromList(cmbDropItem.SelectedIndex - 1);
731+
_dropList[index].ItemId = mEditorItem.Drops[index].ItemId;
735732
}
736733

737-
private void nudDropAmount_ValueChanged(object sender, EventArgs e)
734+
private void nudDropMaxAmount_ValueChanged(object sender, EventArgs e)
738735
{
739-
// This should never be below 1. We shouldn't accept giving 0 items!
740-
nudDropAmount.Value = Math.Max(1, nudDropAmount.Value);
741-
742-
if (lstDrops.SelectedIndex < lstDrops.Items.Count)
736+
int index = lstDrops.SelectedIndex;
737+
if (index < 0 || index > lstDrops.Items.Count)
743738
{
744739
return;
745740
}
746741

747-
mEditorItem.Drops[(int)lstDrops.SelectedIndex].Quantity = (int)nudDropAmount.Value;
748-
UpdateDropValues(true);
742+
mEditorItem.Drops[index].MaxQuantity = (int)nudDropMaxAmount.Value;
743+
_dropList[index].MaxQuantity = mEditorItem.Drops[index].MaxQuantity;
749744
}
750745

751-
private void lstDrops_SelectedIndexChanged(object sender, EventArgs e)
746+
private void nudDropMinAmount_ValueChanged(object sender, EventArgs e)
752747
{
753-
if (lstDrops.SelectedIndex > -1)
748+
int index = lstDrops.SelectedIndex;
749+
if (index < 0 || index > lstDrops.Items.Count)
754750
{
755-
cmbDropItem.SelectedIndex = ItemBase.ListIndex(mEditorItem.Drops[lstDrops.SelectedIndex].ItemId) + 1;
756-
nudDropAmount.Value = mEditorItem.Drops[lstDrops.SelectedIndex].Quantity;
757-
nudDropChance.Value = (decimal)mEditorItem.Drops[lstDrops.SelectedIndex].Chance;
751+
return;
758752
}
753+
754+
mEditorItem.Drops[index].MinQuantity = (int)nudDropMinAmount.Value;
755+
_dropList[index].MinQuantity = mEditorItem.Drops[index].MinQuantity;
759756
}
760757

761-
private void btnDropAdd_Click(object sender, EventArgs e)
758+
private void nudDropChance_ValueChanged(object sender, EventArgs e)
762759
{
763-
mEditorItem.Drops.Add(new Drop());
764-
mEditorItem.Drops[mEditorItem.Drops.Count - 1].ItemId = ItemBase.IdFromList(cmbDropItem.SelectedIndex - 1);
765-
mEditorItem.Drops[mEditorItem.Drops.Count - 1].Quantity = (int)nudDropAmount.Value;
766-
mEditorItem.Drops[mEditorItem.Drops.Count - 1].Chance = (double)nudDropChance.Value;
760+
int index = lstDrops.SelectedIndex;
761+
if (index < 0 || index > lstDrops.Items.Count)
762+
{
763+
return;
764+
}
767765

768-
UpdateDropValues();
766+
mEditorItem.Drops[index].Chance = (double)nudDropChance.Value;
767+
_dropList[index].Chance = mEditorItem.Drops[index].Chance;
769768
}
770769

771-
private void btnDropRemove_Click(object sender, EventArgs e)
770+
private void btnDropAdd_Click(object sender, EventArgs e)
772771
{
773-
if (lstDrops.SelectedIndex > -1)
772+
var drop = new Drop()
774773
{
775-
var i = lstDrops.SelectedIndex;
776-
lstDrops.Items.RemoveAt(i);
777-
mEditorItem.Drops.RemoveAt(i);
778-
}
774+
ItemId = ItemBase.IdFromList(cmbDropItem.SelectedIndex - 1),
775+
MaxQuantity = (int)nudDropMaxAmount.Value,
776+
MinQuantity = (int)nudDropMinAmount.Value,
777+
Chance = (double)nudDropChance.Value
778+
};
779779

780-
UpdateDropValues(true);
780+
mEditorItem.Drops.Add(drop);
781+
782+
_dropList.Add(new NotifiableDrop
783+
{
784+
ItemId = drop.ItemId,
785+
MinQuantity = drop.MinQuantity,
786+
MaxQuantity = drop.MaxQuantity,
787+
Chance = drop.Chance
788+
});
789+
790+
lstDrops.SelectedIndex = _dropList.Count - 1;
781791
}
782792

783-
private void nudDropChance_ValueChanged(object sender, EventArgs e)
793+
private void btnDropRemove_Click(object sender, EventArgs e)
784794
{
785-
if (lstDrops.SelectedIndex < lstDrops.Items.Count)
795+
if (lstDrops.SelectedIndex < 0)
786796
{
787797
return;
788798
}
789799

790-
mEditorItem.Drops[(int)lstDrops.SelectedIndex].Chance = (double)nudDropChance.Value;
791-
UpdateDropValues(true);
800+
var index = lstDrops.SelectedIndex;
801+
mEditorItem.Drops.RemoveAt(index);
802+
_dropList.RemoveAt(index);
792803
}
793804

794805
private void chkIndividualLoot_CheckedChanged(object sender, EventArgs e)

Intersect.Editor/Forms/Editors/frmNpc.resx

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<root>
3-
<!--
3+
<!--
44
Microsoft ResX Schema
5-
5+
66
Version 2.0
7-
8-
The primary goals of this format is to allow a simple XML format
9-
that is mostly human readable. The generation and parsing of the
10-
various data types are done through the TypeConverter classes
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
1111
associated with the data types.
12-
12+
1313
Example:
14-
14+
1515
... ado.net/XML headers & schema ...
1616
<resheader name="resmimetype">text/microsoft-resx</resheader>
1717
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
2626
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
2727
<comment>This is a comment</comment>
2828
</data>
29-
30-
There are any number of "resheader" rows that contain simple
29+
30+
There are any number of "resheader" rows that contain simple
3131
name/value pairs.
32-
33-
Each data row contains a name, and value. The row also contains a
34-
type or mimetype. Type corresponds to a .NET class that support
35-
text/value conversion through the TypeConverter architecture.
36-
Classes that don't support this are serialized and stored with the
32+
33+
Each data row contains a name, and value. The row also contains a
34+
type or mimetype. Type corresponds to a .NET class that support
35+
text/value conversion through the TypeConverter architecture.
36+
Classes that don't support this are serialized and stored with the
3737
mimetype set.
38-
39-
The mimetype is used for serialized objects, and tells the
40-
ResXResourceReader how to depersist the object. This is currently not
38+
39+
The mimetype is used for serialized objects, and tells the
40+
ResXResourceReader how to depersist the object. This is currently not
4141
extensible. For a given mimetype the value must be set accordingly:
42-
43-
Note - application/x-microsoft.net.object.binary.base64 is the format
44-
that the ResXResourceWriter will generate, however the reader can
42+
43+
Note - application/x-microsoft.net.object.binary.base64 is the format
44+
that the ResXResourceWriter will generate, however the reader can
4545
read any of the formats listed below.
46-
46+
4747
mimetype: application/x-microsoft.net.object.binary.base64
48-
value : The object must be serialized with
48+
value : The object must be serialized with
4949
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
5050
: and then encoded with base64 encoding.
5151
5252
mimetype: application/x-microsoft.net.object.soap.base64
53-
value : The object must be serialized with
53+
value : The object must be serialized with
5454
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
5555
: and then encoded with base64 encoding.
5656
5757
mimetype: application/x-microsoft.net.object.bytearray.base64
58-
value : The object must be serialized into a byte array
58+
value : The object must be serialized into a byte array
5959
: using a System.ComponentModel.TypeConverter
6060
: and then encoded with base64 encoding.
6161
-->
@@ -179,6 +179,6 @@
179179
</value>
180180
</data>
181181
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
182-
<value>65</value>
182+
<value>54</value>
183183
</metadata>
184184
</root>

0 commit comments

Comments
 (0)