Skip to content

Commit

Permalink
introduced meter overlay, relics spawn in their locations after being…
Browse files Browse the repository at this point in the history
… given to the player, remove some buggy enemies
  • Loading branch information
TalicZealot committed Mar 12, 2022
1 parent 6c864d2 commit f42492c
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 69 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This tool and the accompanying library and app are open source. The idea is to i
- [Usage](#usage)
- [Updating](#updating)
- [Autotracker](#autotracker)
- [Autosplitter](#autosplitter)
- [Co-Op](#co-op)
- [Khaos-Setup](#Khaos-Setup)
- [Useful links](#useful-links)
Expand Down Expand Up @@ -55,14 +56,17 @@ On lunching the tool it will check for a new release and inform the user. If the
The new tracker has been re-written from the ground up for better performance and usability. Can be manually rescaled. Saves size and location. Locations are drawn on the game map.
Supports OBS html widget overlay located in ```BizHawk\ExternalTools\SotnRandoTools\TrackerOverlay\autotracker.html``` and seed info text in ```BizHawk\ExternalTools\SotnRandoTools\TrackerOverlay\SeedInfo.txt```

## Autosplitter
The autotracker will also automatically start, restart and split when Dracula dies if you have LiveSplit running.

## Co-Op
Coop requires the host to have the port they want to use forwarded. Hosting automatically copies your address(ip:port) to the clipboard. The other player uses that address to connect. Please be careful to not leak your IP!
Bindings over at: [https://taliczealot.github.io/coop/](https://taliczealot.github.io/coop/)

## Khaos-Setup
Inside the folder ```BizHawk\ExternalTools\SotnRandoTools\Khaos\Overlay\``` you will find ```action-queue.html``` and ```timers.html``` which you can add in OBS as web sources.
Inside the folder ```BizHawk\ExternalTools\SotnRandoTools\Khaos\Overlay\``` you will find ```meter.html```, ```action-queue.html``` and ```timers.html``` which you can add in OBS as web sources.
After starting Khaos you will be able to connect to Twitch and start Auto Khaos.
* Clickign "Connect to Twitch" will take you to a website to confirm that you allow SotN Rando Tools to manage Channel Points and see your subscribers. After accepting it will create custom Channel Point rewards for every action and listen for redemptions. When you disconnect or close Khaos the Custom Rewards should get deleted. Please wait for about 20 seconds for all the rewards to get deleted by the API. Redemptions get automatically fulfilled after about a minute and a half, before that the streamer can see them in the redemptions panel in the Khaos window and have the option to refund it.
* Clicking "Connect to Twitch" will take you to a website to confirm that you allow SotN Rando Tools to manage Channel Points and see your subscribers. After accepting it will create custom Channel Point rewards for every action and listen for redemptions. When you disconnect or close Khaos the Custom Rewards should get deleted. Please wait for about 20 seconds for all the rewards to get deleted by the API. Redemptions get automatically fulfilled after about a minute and a half, before that the streamer can see them in the redemptions panel in the Khaos window and have the option to refund it.
* Auto Khaos automatically activates random actions periodically, adhering to the cooldowns. Action frequency is dependant on difficulty setting.

## Useful links
Expand Down
6 changes: 3 additions & 3 deletions SotnRandoTools/src/Constants/Khaos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public static class Khaos
new SearchableActor { Name="Blade Soldier", Hp = 16, Damage = 15, Sprite = 18404 },
new SearchableActor {Hp = 24, Damage = 12, Sprite = 20436 },
new SearchableActor { Name="Bloody Zombie Olrox's Quarters", Hp = 24, Damage = 10, Sprite = 15440 },
new SearchableActor { Name="Olrox Bat", Hp = 13, Damage = 21, Sprite = 64244 },
//new SearchableActor { Name="Olrox Bat", Hp = 13, Damage = 21, Sprite = 64244 },
new SearchableActor { Name="Olrox Skull", Hp = 15, Damage = 23, Sprite = 62980 },
new SearchableActor { Name="Spear Guard Caverns", Hp = 20, Damage = 12, Sprite = 49068 },
new SearchableActor { Name="Bat Caverns", Hp = 1, Damage = 16, Sprite = 36428 },
Expand All @@ -202,7 +202,7 @@ public static class Khaos
new SearchableActor { Name="Gold Medusa Head Death Wing's Lair", Hp = 12, Damage = 7, Sprite = 45800 },
new SearchableActor { Name="Ghost Dancer", Hp = 30, Damage = 56, Sprite = 43916 },
new SearchableActor { Name="Werewolf Inverted Colosseum", Hp = 280, Damage = 40, Sprite = 29328 },
new SearchableActor { Name="Zombie Trevor", Hp = 180, Damage = 40, Sprite = 37884 },
//new SearchableActor { Name="Zombie Trevor", Hp = 180, Damage = 40, Sprite = 37884 },
new SearchableActor {Hp = 10, Damage = 66, Sprite = 14076 },
new SearchableActor {Hp = 43, Damage = 10, Sprite = 2536 },
new SearchableActor {Hp = 12, Damage = 7, Sprite = 9876 },
Expand Down Expand Up @@ -409,7 +409,7 @@ public static class Khaos
public static uint WhiteTigerBallSpeedRight = 0x0000;
public static string WhiteTigerBallSpeedName = "WhiteTigerBallSpeed";

public static List<byte> FireballActorBytes = new List<byte> { 0x00, 0xC0, 0xB2, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x1A, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0x04, 0x00, 0x14, 0x00, 0x00, 0x98, 0x07, 0x0B, 0x80, 0x04, 0x00, 0x01, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08 };
public static List<byte> FireballActorBytes = new List<byte> { 0x00, 0xC0, 0xB2, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x1A, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0x04, 0x00, 0x14, 0x00, 0x00, 0x98, 0x07, 0x0B, 0x80, 0x04, 0x00, 0x01, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08 };
public static List<byte> DarkFireballActorBytes = new List<byte> { 0xE0, 0xBE, 0x7D, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x1B, 0x00, 0x40, 0x78, 0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x04, 0x00, 0x00, 0xC8, 0x07, 0x0B, 0x80, 0x17, 0x00, 0x01, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08 };

public static string[] AcceptedMusicTrackTitles =
Expand Down
54 changes: 33 additions & 21 deletions SotnRandoTools/src/Khaos/KhaosController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ public class KhaosController : IKhaosController
private Cheat music;
#endregion

private int khaosMeter = 0;
private int totalMeterGained = 0;
private int pandoraProgress = 0;
private bool pandoraUsed = false;
private uint alucardMapX = 0;
private uint alucardMapY = 0;
Expand Down Expand Up @@ -383,7 +385,7 @@ public void Gamble(string user = "Khaos")
}
public void KhaoticBurst(string user = "Khaos")
{
notificationService.KhaosMeter += 100;
GainKhaosMeter(100);
notificationService.AddMessage($"{user} used Khaotic Burst");
Alert(toolConfig.Khaos.Actions[(int) Enums.Action.KhaoticBurst]);
}
Expand Down Expand Up @@ -493,7 +495,7 @@ public void SubweaponsOnly(string user = "Khaos")
}
sotnApi.AlucardApi.Subweapon = (Subweapon) roll;
sotnApi.AlucardApi.ActivatePotion(Potion.SmartPotion);
sotnApi.AlucardApi.GrantRelic(Relic.CubeOfZoe);
sotnApi.AlucardApi.GrantRelic(Relic.CubeOfZoe, true);
if (sotnApi.AlucardApi.HasRelic(Relic.GasCloud))
{
sotnApi.AlucardApi.TakeRelic(Relic.GasCloud);
Expand Down Expand Up @@ -831,7 +833,7 @@ void GiveRewards(string user, string item, int relic, int roll)
case 2:
Console.WriteLine($"Heavy help rolled: {Constants.Khaos.ProgressionRelics[relic]}");
SetRelicLocationDisplay(Constants.Khaos.ProgressionRelics[relic], false);
sotnApi.AlucardApi.GrantRelic(Constants.Khaos.ProgressionRelics[relic]);
sotnApi.AlucardApi.GrantRelic(Constants.Khaos.ProgressionRelics[relic], true);
notificationService.AddMessage($"{user} gave you {Constants.Khaos.ProgressionRelics[relic]}");
break;
default:
Expand Down Expand Up @@ -874,16 +876,16 @@ public void Magician(string user = "Khaos")
SpendKhaosMeter();
SetRelicLocationDisplay(Relic.SoulOfBat, false);
SetRelicLocationDisplay(Relic.FormOfMist, false);
sotnApi.AlucardApi.GrantRelic(Relic.SoulOfBat);
sotnApi.AlucardApi.GrantRelic(Relic.FireOfBat);
sotnApi.AlucardApi.GrantRelic(Relic.EchoOfBat);
sotnApi.AlucardApi.GrantRelic(Relic.ForceOfEcho);
sotnApi.AlucardApi.GrantRelic(Relic.SoulOfWolf);
sotnApi.AlucardApi.GrantRelic(Relic.PowerOfWolf);
sotnApi.AlucardApi.GrantRelic(Relic.SkillOfWolf);
sotnApi.AlucardApi.GrantRelic(Relic.FormOfMist);
sotnApi.AlucardApi.GrantRelic(Relic.PowerOfMist);
sotnApi.AlucardApi.GrantRelic(Relic.GasCloud);
sotnApi.AlucardApi.GrantRelic(Relic.SoulOfBat, true);
sotnApi.AlucardApi.GrantRelic(Relic.FireOfBat, true);
sotnApi.AlucardApi.GrantRelic(Relic.EchoOfBat, true);
sotnApi.AlucardApi.GrantRelic(Relic.ForceOfEcho, true);
sotnApi.AlucardApi.GrantRelic(Relic.SoulOfWolf, true);
sotnApi.AlucardApi.GrantRelic(Relic.PowerOfWolf, true);
sotnApi.AlucardApi.GrantRelic(Relic.SkillOfWolf, true);
sotnApi.AlucardApi.GrantRelic(Relic.FormOfMist, true);
sotnApi.AlucardApi.GrantRelic(Relic.PowerOfMist, true);
sotnApi.AlucardApi.GrantRelic(Relic.GasCloud, true);
}

sotnApi.AlucardApi.GrantItemByName("Wizard hat");
Expand Down Expand Up @@ -929,7 +931,7 @@ public void MeltyBlood(string user = "Khaos")
hitbox2Width.Enable();
hitbox2Height.Enable();
SetRelicLocationDisplay(Relic.LeapStone, false);
sotnApi.AlucardApi.GrantRelic(Relic.LeapStone);
sotnApi.AlucardApi.GrantRelic(Relic.LeapStone, true);
meltyTimer.Start();
string message = meterFull ? $"{user} activated GUILTY GEAR" : $"{user} activated Melty Blood";
notificationService.AddMessage(message);
Expand Down Expand Up @@ -1876,7 +1878,7 @@ private void RandomizeRelicsActivate(bool randomizeVladRelics = true)
if ((int) relic < 25)
{
SetRelicLocationDisplay((Relic) relic, false);
sotnApi.AlucardApi.GrantRelic((Relic) relic);
sotnApi.AlucardApi.GrantRelic((Relic) relic, true);
}
}
else
Expand All @@ -1899,14 +1901,14 @@ private void RandomizeRelicsActivate(bool randomizeVladRelics = true)
foreach (Relic relic in Constants.Khaos.FlightRelics[roll])
{
SetRelicLocationDisplay((Relic) relic, false);
sotnApi.AlucardApi.GrantRelic((Relic) relic);
sotnApi.AlucardApi.GrantRelic((Relic) relic, true);
}
}

if (IsInRoomList(Constants.Khaos.SwitchRoom))
{
SetRelicLocationDisplay(Relic.JewelOfOpen, false);
sotnApi.AlucardApi.GrantRelic(Relic.JewelOfOpen);
sotnApi.AlucardApi.GrantRelic(Relic.JewelOfOpen, true);
}
}
private void RandomizeEquipmentSlots()
Expand Down Expand Up @@ -2141,7 +2143,7 @@ private void SubweaponsOnlyOff(object sender, EventArgs e)
hearts.Disable();
if (gasCloudTaken)
{
sotnApi.AlucardApi.GrantRelic(Relic.GasCloud);
sotnApi.AlucardApi.GrantRelic(Relic.GasCloud, true);
gasCloudTaken = false;
}
subweaponsOnlyTimer.Stop();
Expand Down Expand Up @@ -3228,16 +3230,26 @@ private void CheckDashInput()
}
private bool KhaosMeterFull()
{
return notificationService.KhaosMeter >= 100;
return khaosMeter >= 100;
}
private void GainKhaosMeter(short meter)
{
notificationService.KhaosMeter += meter;
khaosMeter += meter;
totalMeterGained += meter;

notificationService.UpdateOverlayMeter(khaosMeter);

if (!pandoraUsed && pandoraProgress < 6 && totalMeterGained >= (toolConfig.Khaos.PandoraTrigger / 7) * (pandoraProgress + 1))
{
string label = "PANDORA";
notificationService.AddMessage(label.Substring(0, pandoraProgress + 1));
pandoraProgress++;
}
}
private void SpendKhaosMeter()
{
notificationService.KhaosMeter -= 100;
khaosMeter -= 100;
notificationService.UpdateOverlayMeter(khaosMeter);
}
private void Alert(Configuration.Models.Action action)
{
Expand Down
44 changes: 44 additions & 0 deletions SotnRandoTools/src/RandoTracker/Tracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -650,66 +650,110 @@ private void UpdateRelics()
{
VladRelicLocationDisplay.HeartOfVladLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.HeartOfVladLocation = String.Empty;
}
break;
case "ToothOfVlad":
if (VladRelicLocationDisplay.ToothOfVladLocation == String.Empty)
{
VladRelicLocationDisplay.ToothOfVladLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.ToothOfVladLocation = String.Empty;
}
break;
case "RibOfVlad":
if (VladRelicLocationDisplay.RibOfVladLocation == String.Empty)
{
VladRelicLocationDisplay.RibOfVladLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.RibOfVladLocation = String.Empty;
}
break;
case "RingOfVlad":
if (VladRelicLocationDisplay.RingOfVladLocation == String.Empty)
{
VladRelicLocationDisplay.RingOfVladLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.RingOfVladLocation = String.Empty;
}
break;
case "EyeOfVlad":
if (VladRelicLocationDisplay.EyeOfVladLocation == String.Empty)
{
VladRelicLocationDisplay.EyeOfVladLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.EyeOfVladLocation = String.Empty;
}
break;
case "SoulOfBat":
if (VladRelicLocationDisplay.BatLocation == String.Empty)
{
VladRelicLocationDisplay.BatLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.BatLocation = String.Empty;
}
break;
case "FormOfMist":
if (VladRelicLocationDisplay.MistLocation == String.Empty)
{
VladRelicLocationDisplay.MistLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.MistLocation = String.Empty;
}
break;
case "JewelOfOpen":
if (VladRelicLocationDisplay.JewelOfOpenLocation == String.Empty)
{
VladRelicLocationDisplay.JewelOfOpenLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.JewelOfOpenLocation = String.Empty;
}
break;
case "GravityBoots":
if (VladRelicLocationDisplay.GravityBootsLocation == String.Empty)
{
VladRelicLocationDisplay.GravityBootsLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.GravityBootsLocation = String.Empty;
}
break;
case "LeapStone":
if (VladRelicLocationDisplay.LepastoneLocation == String.Empty)
{
VladRelicLocationDisplay.LepastoneLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.LepastoneLocation = String.Empty;
}
break;
case "MermanStatue":
if (VladRelicLocationDisplay.MermanLocation == String.Empty)
{
VladRelicLocationDisplay.MermanLocation = location is not null ? location.Name : "";
}
else
{
VladRelicLocationDisplay.MermanLocation = String.Empty;
}
break;
default:
break;
Expand Down
8 changes: 4 additions & 4 deletions SotnRandoTools/src/Services/Autosplitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ public bool AtemptConnect()
{
try
{
pipeClient.Connect(10);
pipeClient.Connect(5);
}
catch
catch (Exception e)
{
Console.WriteLine("Could not connect. " + e.Message);
}
return false;
}
Expand All @@ -36,7 +37,6 @@ public bool AtemptConnect()
}
}


public void StartTImer()
{
SendString("starttimer");
Expand Down Expand Up @@ -96,7 +96,7 @@ private void SendString(string data)
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Pipe Error:" + e.Message);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace SotnRandoTools.Services
public interface INotificationService
{
double Volume { set; }
short KhaosMeter { get; set; }
void AddMessage(string message);
void PlayAlert(string uri);

void StartOverlayServer();
void StopOverlayServer();
void UpdateOverlayMeter(int meter);
void AddOverlayTimer(string name, int duration);
void UpdateOverlayQueue(List<QueuedAction> actionQueue);
void UpdateTrackerOverlay(int relics, int items);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public interface IOverlaySocketServer
{
void StartServer();
void StopServer();
void UpdateMeter(int meter);
void AddTimer(string name, int duration);
void UpdateQueue(List<QueuedAction> actionQueue);
void UpdateTracker(int relics, int items);
Expand Down
Loading

0 comments on commit f42492c

Please sign in to comment.