Skip to content

Commit

Permalink
Merge branch 'release/1.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
adrian-miasik committed Feb 17, 2023
2 parents 24aa65b + 173d5d6 commit f23c791
Show file tree
Hide file tree
Showing 41 changed files with 894 additions and 185 deletions.
148 changes: 32 additions & 116 deletions README.md

Large diffs are not rendered by default.

229 changes: 229 additions & 0 deletions StreamDeckPluginsDota2/DisplayGameClockAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
using System;
using System.Drawing;
using BarRaider.SdTools;
using BarRaider.SdTools.Wrappers;
using Dota2GSI;
using Dota2GSI.Nodes;

namespace StreamDeckPluginsDota2
{
[PluginActionId("com.adrian-miasik.sdpdota2.display-game-clock")]
public class DisplayGameClockAction : InputSimBase
{
// Define colors
private readonly Color m_dayColor = Color.FromArgb(255, 193, 50);
private readonly Color m_nightColor = Color.FromArgb(61, 148, 238);

// Game state (Clock)
private bool m_isSubscribedToGSIEvents;
private GameState m_gameState;

// Clock logic
private int m_lastClockTime;
private int m_currentClockTime;

// Graphics
private TitleParameters m_titleParameters;

public DisplayGameClockAction(ISDConnection connection, InitialPayload payload) : base(connection, payload)
{
// Attempt to subscribe to GSI events
CheckGSI();
}

/// <summary>
/// Subscribes this class to GSI event callback (OnNewGameState) if possible.
/// </summary>
private void CheckGSI()
{
// Initialize GSI / Subscribe to GSI event
if (!m_isSubscribedToGSIEvents)
{
// If GSI hasn't been started...
if(!Program.isGSIInitialized())
{
// Attempt to start GSI...
if (Program.InitializeGSI())
{
// On success...

// Subscribe to GSI event
Program.m_gameStateListener.NewGameState += OnNewGameState;
m_isSubscribedToGSIEvents = true;

Console.WriteLine("TogglePauseAction has subscribed to GSI.");
}
}
// Otherwise, GSI is ready...
else
{
// Subscribe to GSI event
Program.m_gameStateListener.NewGameState += OnNewGameState;
m_isSubscribedToGSIEvents = true;

Console.WriteLine("TogglePauseAction has subscribed to GSI.");
}
}
}

/// <summary>
/// Tick / Updates with new game state (Once per second it seems)
/// </summary>
/// <param name="gamestate"></param>
private void OnNewGameState(GameState gamestate)
{
// Cache for tick check
m_gameState = gamestate;
}

public override void KeyPressed(KeyPayload payload) { }

public override void KeyReleased(KeyPayload payload)
{
// GSI visuals
if (!Program.IsDotaRunning())
{
Connection.SetImageAsync(Program.m_notFound);
}
else if(m_gameState == null)
{
Connection.SetImageAsync(Program.m_standby);
}
}

public override void ReceivedSettings(ReceivedSettingsPayload payload) { }

public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) { }

// Ticks once a second
public override void OnTick()
{
// Prevent tick updates when the action is being interacted with...
if (isKeyPressed)
{
return;
}

if (!Program.IsDotaRunning())
{
// Set to default state
Connection.SetImageAsync(Image.FromFile("images\\actions\\[email protected]"));
Connection.SetTitleAsync(string.Empty);

// Dispose of GSI since it won't be needed when Dota isn't running.
Dispose();
}
else
{
// Otherwise, Dota is running...

// Initialize GSI since we'll need it.
CheckGSI();

// Sanity check GSI
if (m_gameState != null)
{
// We are not in-game...
if (m_gameState.Map.GameState == DOTA_GameState.Undefined)
{
// Show default state
Connection.SetImageAsync(Image.FromFile("images\\actions\\[email protected]"));
Connection.SetTitleAsync(string.Empty);

return;
}

m_currentClockTime = m_gameState.Map.ClockTime;

Render();

// Cache for next tick calculation
m_lastClockTime = m_currentClockTime;
}
else
{
// Otherwise: GSI is not found.

// Set to default state
Connection.SetImageAsync(Image.FromFile("images\\actions\\[email protected]"));
Connection.SetTitleAsync(string.Empty);
}
}
}

private void Render()
{
// Determine day/night cycle
bool isDayTime = !m_gameState.Map.IsNightstalker_Night && m_gameState.Map.IsDaytime;

// Create graphics
Bitmap renderResult = Tools.GenerateGenericKeyImage(out Graphics graphics);

// Render empty background image
RectangleF actionBounds = new RectangleF(0, 0, 144, 144);
Image renderImage = Image.FromFile("images\\actions\\[email protected]");
graphics.DrawImage(renderImage, actionBounds);

// Render center image
Image centerImage;
// If night stalker ult...
if (m_gameState.Map.IsNightstalker_Night)
{
// Night time - Nightstalker ult
centerImage = Image.FromFile("images\\actions\\night-stalker-ultimate.png");
}
// Otherwise...regular clock
else
{
if (m_gameState.Map.IsDaytime)
{
// Day time
centerImage = Program.GenerateSolidColorImage(144, 144, m_dayColor);
}
else
{
// Night time
centerImage = Program.GenerateSolidColorImage(144, 144, m_nightColor);
}
}
RectangleF imageCenterBounds = new RectangleF(4, 4, 136, 92);
graphics.DrawImage(centerImage, imageCenterBounds);

// Render clock time background banner
Brush brush = new SolidBrush(Color.FromArgb(175, 0, 0, 0));
graphics.FillRectangle(brush, new Rectangle(0, 56, 144, 40));

// Render clock time
m_titleParameters = new TitleParameters(FontFamily.GenericSansSerif, FontStyle.Bold, 18,
isDayTime ? m_dayColor : m_nightColor, false, TitleVerticalAlignment.Middle);
graphics.AddTextPath(m_titleParameters, 144, 150,
Program.GetFormattedString(m_currentClockTime));

// Render favicon
if (m_gameState.Map.IsNightstalker_Night)
{
RectangleF faviconBounds = new RectangleF(46, 4, 52, 52);
graphics.DrawImage(Image.FromFile("images\\actions\\night-stalker-favicon.png"), faviconBounds);
}

// Set/Render graphics
Connection.SetImageAsync(renderResult);

// Dispose
graphics.Dispose();
}

public override void Dispose()
{
if (Program.isGSIInitialized() && m_isSubscribedToGSIEvents)
{
// Unsub
Program.m_gameStateListener.NewGameState -= OnNewGameState;
m_gameState = null;
m_isSubscribedToGSIEvents = false;

Console.WriteLine("DisplayGameClockAction has unsubscribed from GSI.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@

namespace StreamDeckPluginsDota2
{
public class RuneBase : PluginBase
// TODO: Create a base class w/ GSI integration
public class InputSimBase : PluginBase
{
public InputSimulator InputSimulator;
protected InputSimulator InputSimulator;
protected bool isKeyPressed;

public RuneBase(ISDConnection connection, InitialPayload payload) : base(connection, payload)
protected InputSimBase(ISDConnection connection, InitialPayload payload) : base(connection, payload)
{
InputSimulator = new InputSimulator();
}

public override void KeyPressed(KeyPayload payload)
{
isKeyPressed = true;
}

public override void KeyReleased(KeyPayload payload)
{
isKeyPressed = false;
}

public override void ReceivedSettings(ReceivedSettingsPayload payload)
Expand Down
Loading

0 comments on commit f23c791

Please sign in to comment.