diff --git a/ItemChanger/Deployers/EnemyBlockerDeployer.cs b/ItemChanger/Deployers/EnemyBlockerDeployer.cs
new file mode 100644
index 00000000..b33154af
--- /dev/null
+++ b/ItemChanger/Deployers/EnemyBlockerDeployer.cs
@@ -0,0 +1,19 @@
+namespace ItemChanger.Deployers
+{
+ ///
+ /// Deployer which creates a region which enemies cannot enter.
+ ///
+ public record EnemyBlockerDeployer : Deployer
+ {
+ public float Width { get; init; }
+ public float Height { get; init; }
+
+ public override GameObject Instantiate()
+ {
+ GameObject go = new() { layer = 15 };
+ BoxCollider2D box = go.AddComponent();
+ box.size = new(Width, Height);
+ return go;
+ }
+ }
+}
diff --git a/ItemChanger/Deployers/HintBoxDeployer.cs b/ItemChanger/Deployers/HintBoxDeployer.cs
new file mode 100644
index 00000000..af5164a7
--- /dev/null
+++ b/ItemChanger/Deployers/HintBoxDeployer.cs
@@ -0,0 +1,22 @@
+using ItemChanger.Components;
+
+namespace ItemChanger.Deployers
+{
+ ///
+ /// Deployer which creates a HintBox, a region which displays a dream dialogue message when the hero enters.
+ ///
+ public record HintBoxDeployer : Deployer
+ {
+ public float Width { get; init; } = 5f;
+ public float Height { get; init; } = 5f;
+ public IString Text { get; init; }
+
+
+ public override GameObject Instantiate()
+ {
+ HintBox box = HintBox.Create(new Vector2(X, Y), new Vector2(Width, Height));
+ box.GetDisplayText = Text.GetValue;
+ return box.gameObject;
+ }
+ }
+}
diff --git a/ItemChanger/Tags/SetIBoolOnGiveTag.cs b/ItemChanger/Tags/SetIBoolOnGiveTag.cs
new file mode 100644
index 00000000..d8102e6d
--- /dev/null
+++ b/ItemChanger/Tags/SetIBoolOnGiveTag.cs
@@ -0,0 +1,57 @@
+namespace ItemChanger.Tags
+{
+ ///
+ /// Tag which sets an IWriteableBool when its parent item is given.
+ ///
If attached to a location or placement, sets the bool when VisitState.ObtainedAnyItem is first set on the placement.
+ ///
+ public class SetIBoolOnGiveTag : Tag
+ {
+ public IWritableBool Bool;
+ public bool value = true;
+
+ public override void Load(object parent)
+ {
+ if (parent is AbstractItem item)
+ {
+ item.OnGive += OnGive;
+ }
+ else
+ {
+ AbstractPlacement placement = parent as AbstractPlacement ?? (parent as AbstractLocation)?.Placement;
+ if (placement is not null)
+ {
+ placement.OnVisitStateChanged += OnVisitStateChanged;
+ }
+ }
+ }
+
+ public override void Unload(object parent)
+ {
+ if (parent is AbstractItem item)
+ {
+ item.OnGive -= OnGive;
+ }
+ else
+ {
+ AbstractPlacement placement = parent as AbstractPlacement ?? (parent as AbstractLocation)?.Placement;
+ if (placement is not null)
+ {
+ placement.OnVisitStateChanged -= OnVisitStateChanged;
+ }
+ }
+ }
+
+ private void OnGive(ReadOnlyGiveEventArgs obj)
+ {
+ Bool.Value = value;
+ }
+
+ private void OnVisitStateChanged(VisitStateChangedEventArgs obj)
+ {
+ if (obj.NewFlags.HasFlag(VisitState.ObtainedAnyItem) && !obj.Orig.HasFlag(VisitState.ObtainedAnyItem))
+ {
+ Bool.Value = value;
+ }
+ }
+ }
+}
diff --git a/ItemChanger/Tags/SetPDBoolOnGiveTag.cs b/ItemChanger/Tags/SetPDBoolOnGiveTag.cs
index faef34ea..ed9b3e43 100644
--- a/ItemChanger/Tags/SetPDBoolOnGiveTag.cs
+++ b/ItemChanger/Tags/SetPDBoolOnGiveTag.cs
@@ -4,6 +4,7 @@
/// Tag which adds setting a PlayerData bool as a side effect to an item.
///
Be warned that this effect is tied to the tag's parent, regardless of how it is modified during Give.
///
+ [Obsolete("Use SetIBoolOnGiveTag instead.")]
public class SetPDBoolOnGiveTag : Tag
{
public string fieldName;
diff --git a/ItemChanger/Util/TabletUtility.cs b/ItemChanger/Util/TabletUtility.cs
index 2c3251b2..26c7898b 100644
--- a/ItemChanger/Util/TabletUtility.cs
+++ b/ItemChanger/Util/TabletUtility.cs
@@ -17,7 +17,7 @@ public static GameObject InstantiateTablet(string tabletName)
GameObject lit_tablet = tablet.transform.Find("lit_tablet").gameObject; // doesn't appear after instantiation, for some reason
GameObject lit = new GameObject();
lit.transform.SetParent(tablet.transform);
- lit.transform.localPosition = new Vector3(-0.1f, 0.1f, -1.8f);
+ lit.transform.localPosition = new Vector3(-0.1f, 0.1f, -3f);
lit.transform.localScale = Vector3.one;
lit.AddComponent().sprite = lit_tablet.GetComponent().sprite;
lit.GetComponent().color = new Color(1, 1, 1, 0.8f);
diff --git a/ItemChanger/VanillaShops.cs b/ItemChanger/VanillaShops.cs
index 9d8a3148..709a1b04 100644
--- a/ItemChanger/VanillaShops.cs
+++ b/ItemChanger/VanillaShops.cs
@@ -1,34 +1,38 @@
-namespace ItemChanger
+/*
+using ItemChanger.Locations;
+using ItemChanger.Placements;
+using ItemChanger.Tags;
+
+namespace ItemChanger
{
static class VanillaShops
{
- /*
public static AbstractPlacement[] GetVanillaShops()
{
AbstractItem mask1 = Finder.GetItem(ItemNames.Mask_Shard);
mask1.AddTag().Cost = Cost.NewGeoCost(150);
- mask1.AddTag().fieldName = nameof(PlayerData.slyShellFrag1);
+ mask1.AddTag().Bool = new PDBool(nameof(PlayerData.slyShellFrag1));
AbstractItem mask2 = Finder.GetItem(ItemNames.Mask_Shard);
mask2.AddTag().Cost = Cost.NewGeoCost(500);
- mask2.AddTag().fieldName = nameof(PlayerData.slyShellFrag2);
+ mask2.AddTag().Bool = new PDBool(nameof(PlayerData.slyShellFrag2));
mask2.AddTag().fieldName = nameof(PlayerData.slyShellFrag1);
AbstractItem mask3 = Finder.GetItem(ItemNames.Mask_Shard);
mask3.AddTag().Cost = Cost.NewGeoCost(800);
- mask3.AddTag().fieldName = nameof(PlayerData.slyShellFrag3);
+ mask3.AddTag().Bool = new PDBool(nameof(PlayerData.slyShellFrag3));
mask3.AddTag().fieldName = nameof(PlayerData.slyShellFrag2);
mask3.AddTag().fieldName = nameof(PlayerData.gaveSlykey);
AbstractItem mask4 = Finder.GetItem(ItemNames.Mask_Shard);
mask4.AddTag().Cost = Cost.NewGeoCost(1500);
- mask4.AddTag().fieldName = nameof(PlayerData.slyShellFrag4);
+ mask4.AddTag().Bool = new PDBool(nameof(PlayerData.slyShellFrag4));
mask4.AddTag().fieldName = nameof(PlayerData.slyShellFrag3);
mask4.AddTag().fieldName = nameof(PlayerData.gaveSlykey);
AbstractItem vessel1 = Finder.GetItem(ItemNames.Vessel_Fragment);
vessel1.AddTag().Cost = Cost.NewGeoCost(550);
- vessel1.AddTag().fieldName = nameof(PlayerData.slyVesselFrag1);
+ vessel1.AddTag().Bool = new PDBool(nameof(PlayerData.slyVesselFrag1));
AbstractItem vessel2 = Finder.GetItem(ItemNames.Vessel_Fragment);
vessel2.AddTag().Cost = Cost.NewGeoCost(900);
@@ -58,34 +62,34 @@ public static AbstractPlacement[] GetVanillaShops()
AbstractItem rancid_egg = Finder.GetItem(ItemNames.Rancid_Egg);
rancid_egg.AddTag().Cost = Cost.NewGeoCost(60);
- rancid_egg.AddTag().fieldName = nameof(PlayerData.slyRancidEgg);
+ rancid_egg.AddTag().Bool = new PDBool(nameof(PlayerData.slyRancidEgg));
AbstractItem simple_key = Finder.GetItem(ItemNames.Simple_Key);
simple_key.AddTag().Cost = Cost.NewGeoCost(950);
- simple_key.AddTag().fieldName = nameof(PlayerData.slySimpleKey);
+ simple_key.AddTag().Bool = new PDBool(nameof(PlayerData.slySimpleKey));
- AbstractPlacement sly = new ShopPlacement
+ AbstractPlacement sly = new ShopPlacement(LocationNames.Sly)
{
Location = Finder.GetLocation(LocationNames.Sly) as ShopLocation,
- Items = new List
- {
- mask1,
- mask2,
- mask3,
- mask4,
- vessel1,
- vessel2,
- elegant_key,
- lantern,
- gathering_swarm,
- stalwart_shell,
- heavy_blow,
- sprintmaster,
- rancid_egg,
- simple_key,
- },
- };
+ }
+ .Add(new List
+ {
+ mask1,
+ mask2,
+ mask3,
+ mask4,
+ vessel1,
+ vessel2,
+ elegant_key,
+ lantern,
+ gathering_swarm,
+ stalwart_shell,
+ heavy_blow,
+ sprintmaster,
+ rancid_egg,
+ simple_key,
+ });
AbstractItem wayward_compass = Finder.GetItem(ItemNames.Wayward_Compass);
@@ -201,40 +205,40 @@ public static AbstractPlacement[] GetVanillaShops()
gleaming_marker.AddTag().Cost = Cost.NewGeoCost(210);
gleaming_marker.AddTag().fieldName = nameof(PlayerData.hasDash);
- AbstractPlacement iselda = new ShopPlacement
+ AbstractPlacement iselda = new ShopPlacement(LocationNames.Iselda)
{
Location = Finder.GetLocation(LocationNames.Iselda) as ShopLocation,
- Items = new List
- {
- wayward_compass,
- quill,
- crossroads_map,
- greenpath_map,
- canyon_map,
- wastes_map,
- city_map,
- waterways_map,
- mines_map,
- rg_map,
- cliffs_map,
- deepnest_map,
- edge_map,
- gardens_map,
- basin_map,
- bench_pin,
- cocoon_pin,
- root_pin,
- warrior_pin,
- vendor_pin,
- stag_pin,
- tram_pin,
- spa_pin,
- scarab_marker,
- shell_marker,
- token_marker,
- gleaming_marker
- },
- };
+ }
+ .Add(new List
+ {
+ wayward_compass,
+ quill,
+ crossroads_map,
+ greenpath_map,
+ canyon_map,
+ wastes_map,
+ city_map,
+ waterways_map,
+ mines_map,
+ rg_map,
+ cliffs_map,
+ deepnest_map,
+ edge_map,
+ gardens_map,
+ basin_map,
+ bench_pin,
+ cocoon_pin,
+ root_pin,
+ warrior_pin,
+ vendor_pin,
+ stag_pin,
+ tram_pin,
+ spa_pin,
+ scarab_marker,
+ shell_marker,
+ token_marker,
+ gleaming_marker
+ });
AbstractItem fragile_heart = Finder.GetItem(ItemNames.Fragile_Heart);
fragile_heart.AddTag().Cost = Cost.NewGeoCost(350);
@@ -263,19 +267,19 @@ public static AbstractPlacement[] GetVanillaShops()
repair_strength.AddTag().fieldName = nameof(PlayerData.brokenCharm_25);
//repair_strength.AddTag().Persistence = Persistence.Persistent;
- AbstractPlacement leg_eater = new ShopPlacement
+ AbstractPlacement leg_eater = new ShopPlacement(LocationNames.Leg_Eater)
{
Location = Finder.GetLocation(LocationNames.Leg_Eater) as ShopLocation,
- Items = new List
- {
- fragile_heart,
- repair_heart,
- fragile_greed,
- repair_greed,
- fragile_strength,
- repair_strength
- },
- };
+ }
+ .Add(new List
+ {
+ fragile_heart,
+ repair_heart,
+ fragile_greed,
+ repair_greed,
+ fragile_strength,
+ repair_strength
+ });
AbstractItem lifeblood_heart = Finder.GetItem(ItemNames.Lifeblood_Heart);
lifeblood_heart.AddTag().Cost = Cost.NewGeoCost(250);
@@ -294,45 +298,45 @@ public static AbstractPlacement[] GetVanillaShops()
AbstractItem notch1 = Finder.GetItem(ItemNames.Charm_Notch);
notch1.AddTag().Cost = Cost.NewGeoCost(120)
- + new PDIntCost { fieldName = nameof(PlayerData.charmsOwned), amount = 5, uiText = "Requires 5 charms" };
- notch1.AddTag().fieldName = nameof(PlayerData.salubraNotch1);
+ + new PDIntCost(5, nameof(PlayerData.charmsOwned), "Requires 5 charms");
+ notch1.AddTag().Bool = new PDBool(nameof(PlayerData.salubraNotch1));
AbstractItem notch2 = Finder.GetItem(ItemNames.Charm_Notch);
notch2.AddTag().Cost = Cost.NewGeoCost(500)
- + new PDIntCost { fieldName = nameof(PlayerData.charmsOwned), amount = 10, uiText = "Requires 10 charms" };
- notch2.AddTag().fieldName = nameof(PlayerData.salubraNotch2);
+ + new PDIntCost(10, nameof(PlayerData.charmsOwned), "Requires 10 charms");
+ notch2.AddTag().Bool = new PDBool(nameof(PlayerData.salubraNotch2));
AbstractItem notch3 = Finder.GetItem(ItemNames.Charm_Notch);
notch3.AddTag().Cost = Cost.NewGeoCost(900)
- + new PDIntCost { fieldName = nameof(PlayerData.charmsOwned), amount = 18, uiText = "Requires 18 charms" };
- notch3.AddTag().fieldName = nameof(PlayerData.salubraNotch3);
+ + new PDIntCost (18, nameof(PlayerData.charmsOwned), "Requires 18 charms");
+ notch3.AddTag().Bool = new PDBool(nameof(PlayerData.salubraNotch3));
AbstractItem notch4 = Finder.GetItem(ItemNames.Charm_Notch);
notch4.AddTag().Cost = Cost.NewGeoCost(120)
- + new PDIntCost { fieldName = nameof(PlayerData.charmsOwned), amount = 25, uiText = "Requires 25 charms" };
- notch4.AddTag().fieldName = nameof(PlayerData.salubraNotch4);
+ + new PDIntCost (25, nameof(PlayerData.charmsOwned), "Requires 25 charms");
+ notch4.AddTag().Bool = new PDBool(nameof(PlayerData.salubraNotch4));
AbstractItem blessing = Finder.GetItem(ItemNames.Salubras_Blessing);
blessing.AddTag().Cost = Cost.NewGeoCost(800);
blessing.AddTag().fieldName = nameof(PlayerData.salubraNotch4);
- AbstractPlacement salubra = new ShopPlacement
+ AbstractPlacement salubra = new ShopPlacement(LocationNames.Salubra)
{
Location = Finder.GetLocation(LocationNames.Salubra) as ShopLocation,
- Items = new List
- {
- lifeblood_heart,
- longnail,
- steady_body,
- shaman_stone,
- quick_focus,
- notch1,
- notch2,
- notch3,
- notch4,
- blessing
- },
- };
+ }
+ .Add(new List
+ {
+ lifeblood_heart,
+ longnail,
+ steady_body,
+ shaman_stone,
+ quick_focus,
+ notch1,
+ notch2,
+ notch3,
+ notch4,
+ blessing
+ });
return new[]
{
@@ -344,6 +348,6 @@ public static void Print()
{
Finder.Serialize("vanilla.json", GetVanillaShops());
}
- */
}
}
+*/