Skip to content

Commit

Permalink
Room Rando logic fixes and wall behaviour changes
Browse files Browse the repository at this point in the history
  • Loading branch information
nerthul11 committed Jul 19, 2024
1 parent ae5bcee commit b323b64
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 77 deletions.
2 changes: 1 addition & 1 deletion BreakableWallRandomizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace BreakableWallRandomizer
public class BreakableWallRandomizer : Mod, IGlobalSettings<BWR_Settings>
{
new public string GetName() => "Breakable Wall Randomizer";
public override string GetVersion() => "3.0.1.1";
public override string GetVersion() => "3.0.1.2";
public BWR_Settings GS { get; set; } = new();
private static BreakableWallRandomizer _instance;
public BreakableWallRandomizer() : base()
Expand Down
4 changes: 2 additions & 2 deletions BreakableWallRandomizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<Product>BreakableWallRandomizer</Product>
<Description>A Randomizer add-on for wall and floor objects.</Description>
<Copyright>Copyright ©2023</Copyright>
<AssemblyVersion>3.0.1.1</AssemblyVersion>
<FileVersion>3.0.1.1</FileVersion>
<AssemblyVersion>3.0.1.2</AssemblyVersion>
<FileVersion>3.0.1.2</FileVersion>
<OutputPath>bin\$(Configuration)\</OutputPath>
<LangVersion>latest</LangVersion>
</PropertyGroup>
Expand Down
30 changes: 30 additions & 0 deletions FSM/CustomBoolCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using HutongGames.PlayMaker;

namespace BreakableWallRandomizer.Fsm
{
internal class CustomFsmBooleanCheck : FsmStateAction
{
private bool value;
private string trueEvent;
private string falseEvent;

public CustomFsmBooleanCheck(bool _value, string _trueEvent, string _falseEvent)
{
value = _value;
trueEvent = _trueEvent;
falseEvent = _falseEvent;
}
public override void OnEnter()
{
if (value)
{
Fsm.Event(trueEvent);
}
else
{
Fsm.Event(falseEvent);
}
Finish();
}
}
}
4 changes: 2 additions & 2 deletions IC/BreakableWallItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override void GiveImmediate(GiveInfo info)
if (wall.name.StartsWith("Dive_Floor") && !BreakableWallModule.Instance.UnlockedDives.Contains(name))
BreakableWallModule.Instance.UnlockedDives.Add(wall.name);

// If we're already in the same scene as the wall, break it. The wall's FSM should spawn a shiny.
// If we're already in the same scene as the wall, break it.
if (GameManager.instance.sceneName == wall.sceneName)
GameObject.Find(wall.gameObject).LocateMyFSM(wall.fsmType).SetState("BreakSameScene");
}
Expand All @@ -89,7 +89,7 @@ public override void GiveImmediate(GiveInfo info)
if (name.StartsWith("Dive_Floor") && !BreakableWallModule.Instance.UnlockedDives.Contains(name))
BreakableWallModule.Instance.UnlockedDives.Add(name);

// If we're already in the same scene as the wall, break it. The wall's FSM should spawn a shiny.
// If we're already in the same scene as the wall, break it.
if (GameManager.instance.sceneName == sceneName)
GameObject.Find(gameObject).LocateMyFSM(fsmType).SetState("BreakSameScene");
}
Expand Down
120 changes: 58 additions & 62 deletions IC/BreakableWallLocation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BreakableWallRandomizer.Modules;
using BreakableWallRandomizer.Fsm;
using BreakableWallRandomizer.Modules;
using HutongGames.PlayMaker.Actions;
using ItemChanger;
using ItemChanger.Locations;
Expand Down Expand Up @@ -111,7 +112,7 @@ protected override void OnUnload()
}
}

private void MakeWallPassable(GameObject go)
private void MakeWallPassable(GameObject go, bool destroy)
{
foreach (var objectName in alsoDestroy)
{
Expand All @@ -121,13 +122,13 @@ private void MakeWallPassable(GameObject go)
GameObject.Destroy(obj);
} catch { }
}
Recursive_MakeWallPassable(go);
Recursive_MakeWallPassable(go, destroy);
}

// Recursively set all colliders as triggers on a given gameObject.
// Also recursively set any SpriteRenderers on a given gameObject to 0.5 alpha.
// Also remove any object called "Camera lock" or any textures beginning with msk_.
private void Recursive_MakeWallPassable(GameObject go)
private void Recursive_MakeWallPassable(GameObject go, bool destroy)
{
foreach (var collider in go.GetComponents<Collider2D>())
{
Expand Down Expand Up @@ -161,7 +162,9 @@ private void Recursive_MakeWallPassable(GameObject go)

for (var i = 0; i < go.transform.childCount; i++)
{
MakeWallPassable(go.transform.GetChild(i).gameObject);
MakeWallPassable(go.transform.GetChild(i).gameObject, destroy);
if (destroy)
GameObject.Destroy(go);
}
}

Expand All @@ -184,6 +187,25 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)
if (wall.fsmType != fsm.FsmName)
continue;

var originalIdleStateName = wall.fsmType switch
{
"quake_floor" => "Solid",

"Detect Quake" => "Detect",

_ => "Idle"
};

// Copy sound and particles from original
var originalBreakStateName = wall.fsmType switch
{
"quake_floor" => "Glass",

"Detect Quake" => "Break 2",

_ => "Break"
};

// If a location is present, it means that it's not vanilla
BreakableWallModule.Instance.vanillaWalls.RemoveAll(wall => wall.name == name);

Expand All @@ -210,11 +232,10 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)
} else if (wall.fsmType == "quake_floor")
{
fsm.ChangeTransition("Init", "ACTIVATE", "Solid");
fsm.RemoveAction("Transient", 0); // Sets the floor to a trigger
if (fsm.GetState("Transient").GetActions<SetBoxColliderTrigger>().Length >= 1)
fsm.RemoveAction("Transient", 0);
if (fsm.GetState("Solid").GetActions<SetBoxColliderTrigger>().Length >= 1)
{
fsm.RemoveAction("Solid", 0); // Sets the floor to a triggern't
}
fsm.RemoveAction("Solid", 0);

var collider = fsm.gameObject.GetComponent<BoxCollider2D>();
collider.isTrigger = true; // Make the first collider always a trigger
Expand All @@ -228,6 +249,12 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)
fsm.ChangeTransition("Init", "ACTIVATE", "Detect");
}

// If the wall item had been obtained when calling GiveItem, destroy the wall on trigger.
fsm.AddState("DeleteWall");
fsm.AddCustomAction("DeleteWall", () => MakeWallPassable(fsm.gameObject, true));
fsm.AddTransition("DeleteWall", "FINISHED", originalBreakStateName);

// Add GiveItem state
fsm.AddState("GiveItem");
fsm.AddCustomAction("GiveItem", () =>
{
Expand All @@ -238,27 +265,18 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)
});
Placement.AddVisitFlag(VisitState.Opened);
if (BreakableWallModule.Instance.UnlockedBreakableWalls.Contains(wall.name))
{
// Delete the wall entirely.
if (fsmType == "quake_floor")
fsm.SetState("Destroy");
else if (fsmType == "Detect Quake")
fsm.SetState("Break 2");
else
fsm.SetState("Break");
}
});
fsm.AddAction("GiveItem", new CustomFsmBooleanCheck(
BreakableWallModule.Instance.UnlockedBreakableWalls.Contains(wall.name), "OBTAINED", ""
));
fsm.AddTransition("GiveItem", "OBTAINED", "DeleteWall");

// If we already unlocked this wall, and items are still left there, make it passable.
if (BreakableWallModule.Instance.UnlockedBreakableWalls.Contains(wall.name))
{
// If items are left, make wall semi-transparent and passable
// If items are left, make wall semi-transparent and passable.
if (!Placement.AllObtained())
{
MakeWallPassable(fsm.gameObject);
}
MakeWallPassable(fsm.gameObject, false);
else
{
// Ensure the wall deletes on-load.
Expand Down Expand Up @@ -287,25 +305,6 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)
// ...and there are items left to collect:
else
{
var originalIdleStateName = wall.fsmType switch
{
"quake_floor" => "Solid",

"Detect Quake" => "Detect",

_ => "Idle"
};

// Copy sound and particles from original
var originalBreakStateName = wall.fsmType switch
{
"quake_floor" => "Glass",

"Detect Quake" => "Break 2",

_ => "Break"
};

foreach (var action in fsm.GetState(originalBreakStateName).Actions)
{
if (action is AudioPlayerOneShotSingle or PlayParticleEmitter or AudioPlayerOneShot)
Expand All @@ -319,25 +318,22 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)

fsm.AddState("BreakSameScene");

fsm.InsertCustomAction("BreakSameScene", () =>
// In any of the cases, the wall is expected to become passable.
fsm.AddCustomAction("BreakSameScene", () =>
{
if (Placement.AllObtained())
{
MakeWallPassable(fsm.gameObject);
fsm.SetState(originalIdleStateName);
}
else
{
if (wall.fsmType == "quake_floor")
{
MakeWallPassable(fsm.gameObject);
} // ensure everything is passable.
fsm.SetState(originalBreakStateName);
}
MakeWallPassable(fsm.gameObject, Placement.AllObtained());
Placement.AddVisitFlag(VisitState.Opened);
}, 0);
}
});

// If placement is cleared, make the wall disappear. Otherwise, set to hittable state.
fsm.AddAction("BreakSameScene", new CustomFsmBooleanCheck(
Placement.AllObtained(),
"CLEARED",
"UNCLEARED"
));
fsm.AddTransition("BreakSameScene", "UNCLEARED", originalIdleStateName);
fsm.AddTransition("BreakSameScene", "CLEARED", originalBreakStateName);
}
}

if (wall.fsmType == "breakable_wall_v2")
Expand All @@ -356,7 +352,7 @@ private void ModifyWallBehaviour(PlayMakerFSM fsm)
fsm.ChangeTransition("Hit", "HIT 3", "GiveItem");
} else if (wall.fsmType == "quake_floor")
{
fsm.ChangeTransition("PD Bool?", "FINISHED", "GiveItem");
fsm.ChangeTransition("Transient", "DESTROY", "GiveItem");
} else if (wall.fsmType == "Detect Quake")
{
fsm.ChangeTransition("Quake Hit", "FINISHED", "GiveItem");
Expand Down Expand Up @@ -393,4 +389,4 @@ private void ManageKPCollapse(PlayMakerFSM fsm)
}
}
}
}
}
Loading

0 comments on commit b323b64

Please sign in to comment.