Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions RPGPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,26 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="RPGPlugin\Roles\Behavior\ClassesBase.cs" />
<Compile Include="RPGPlugin\Roles\baseClasses\ClassesBase.cs" />
<Compile Include="RPGPlugin\Roles\baseClasses\configBase.cs" />
<Compile Include="RPGPlugin\Roles\Behavior\HunterClass.cs" />
<Compile Include="RPGPlugin\Roles\Behavior\MinerClass.cs" />
<Compile Include="RPGPlugin\Roles\Behavior\SampleClass.cs" />
<Compile Include="RPGPlugin\Roles\Behavior\WarriorClass.cs" />
<Compile Include="RPGPlugin\Roles\Config\configBase.cs" />
<Compile Include="RPGPlugin\Roles\Config\HunterConfig.cs" />
<Compile Include="RPGPlugin\Roles\Config\MinerConfig.cs" />
<Compile Include="RPGPlugin\Roles\Config\PlayerData.cs" />
<Compile Include="RPGPlugin\Roles\Config\SampleConfig.cs" />
<Compile Include="RPGPlugin\Roles\Config\WarriorConfig.cs" />
<Compile Include="RPGPlugin\Roles\View\Hunter.xaml.cs">
<DependentUpon>Hunter.xaml</DependentUpon>
</Compile>
<Compile Include="RPGPlugin\Roles\View\Miner.xaml.cs">
<DependentUpon>Miner.xaml</DependentUpon>
</Compile>
<Compile Include="RPGPlugin\Roles\View\Warrior.xaml.cs">
<DependentUpon>Warrior.xaml</DependentUpon>
</Compile>
<Compile Include="RPGPlugin\RPGPluginManager.cs" />
<Compile Include="RPGPlugin\RPGPlugin.cs" />
<Compile Include="RPGPlugin\RPGPluginCommands.cs" />
Expand All @@ -151,6 +160,7 @@
<DependentUpon>RPGPluginControl.xaml</DependentUpon>
</Compile>
<Compile Include="RPGPlugin\Utils\FileManager.cs" />
<Compile Include="RPGPlugin\Utils\HelperFunctions.cs" />
<Compile Include="RPGPlugin\Utils\RoleManager.cs" />
<Compile Include="RPGPlugin\Utils\Objects.cs" />
<Compile Include="RPGPlugin\Utils\RPGPluginConfig.cs" />
Expand Down Expand Up @@ -179,6 +189,9 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="RPGPlugin\Roles\View\Hunter.xaml" />
<Page Include="RPGPlugin\Roles\View\Miner.xaml" />
<Page Include="RPGPlugin\Roles\View\Warrior.xaml" />
<Page Include="RPGPlugin\Torch GUI\EditItemWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand All @@ -196,9 +209,6 @@
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="RPGPlugin\Roles\View\" />
</ItemGroup>
<Target Name="Zip" BeforeTargets="AfterBuild">
<MakeDir Directories="$(SolutionDir)\Build\" />
<ZipDirectory SourceDirectory="$(OutputPath)" DestinationFile="$(SolutionDir)\Build\$(MSBuildProjectName).zip" Overwrite="true" />
Expand Down
61 changes: 34 additions & 27 deletions RPGPlugin/RPGPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Xml.Serialization;
using RPGPlugin.PointManagementSystem;
using Sandbox.Engine.Multiplayer;
Expand All @@ -18,8 +21,8 @@
using Torch.Session;
using VRage.GameServices;
using RPGPlugin.Utils;
using Sandbox.Game.Multiplayer;
using Newtonsoft.Json;
using Torch.Collections;
using Timer = System.Timers.Timer;


namespace RPGPlugin
Expand All @@ -30,6 +33,8 @@ public class Roles : TorchPluginBase, IWpfPlugin
public static ConcurrentDictionary<ulong, PlayerManager> PlayerManagers = new ConcurrentDictionary<ulong, PlayerManager>();
public static Dictionary<string, configBase> classConfigs = new Dictionary<string, configBase>();
public static Dictionary<string, ClassesBase> roles = new Dictionary<string, ClassesBase>();
public MtObservableSortedDictionary<string, UserControl> classViews = new MtObservableSortedDictionary<string, UserControl>();
public readonly Dispatcher MainDispatcher = Dispatcher.CurrentDispatcher;
private Timer _delayManagers = new Timer(TimeSpan.FromSeconds(5).TotalMilliseconds);
public PatchManager patchManager;
public PatchContext patchContext;
Expand All @@ -45,14 +50,12 @@ public class Roles : TorchPluginBase, IWpfPlugin
private Persistent<RPGPluginConfig> _config;
public RPGPluginConfig Config => _config?.Data;

public override void Init(ITorchBase torch)
public override async void Init(ITorchBase torch)
{
base.Init(torch);
Roles.Log.Warn($"MainPlugin Thread => {Thread.CurrentThread.ManagedThreadId}");
Instance = this;
SetupConfig();

// Registration of role configuration classes
// This is called on class auto-load!
await SetupConfig();

_delayManagers.Stop();
_delayManagers.Elapsed += DelayManagersOnElapsed;
Expand All @@ -62,12 +65,11 @@ public override void Init(ITorchBase torch)
else
Log.Warn("No session manager loaded!");

patchManager = DependencyProviderExtensions.GetManager<PatchManager>(torch.Managers);
patchManager = torch.Managers.GetManager<PatchManager>();
patchContext = patchManager.AcquireContext();
DrillPatch.Patch(patchContext);
RoleAgent.LoadAllConfigs();
RoleAgent.LoadAllClasses();
Save();
await Save();
await RoleAgent.LoadAllRoles();; // Give the system time to write and release the saved config file
}

private void DelayManagersOnElapsed(object sender, ElapsedEventArgs e)
Expand Down Expand Up @@ -119,8 +121,6 @@ private void SessionChanged(ITorchSession session, TorchSessionState state)
private async void PlayerDisconnected(ulong steamID, MyChatMemberStateChangeEnum myChatMemberStateChangeEnum)
{
// Unload them from the system, free up resources.
MyPlayer player = MySession.Static.Players.TryGetPlayerBySteamId(steamID);

if (!PlayerManagers.ContainsKey(steamID))
{
Log.Error($"Unable to save profile for player [SteamID:{steamID}], it was probably not loaded.");
Expand All @@ -142,27 +142,19 @@ private async void SaveAllPlayersForShutDown()

private static void PlayerConnected(ulong steamID, string s)
{
long playerId = Sync.Players.TryGetIdentityId(steamID);
PlayerManager roleManager = new PlayerManager();
roleManager.InitAsync(steamID);
PlayerManagers.TryAdd(steamID, roleManager);
}

private void SetupConfig()
private async Task SetupConfig()
{
string dataPath = Path.Combine(StoragePath, "RPGPlugin");
string playerDataPath = Path.Combine(dataPath, "Player Data");

// create directories if they do not exist
Directory.CreateDirectory(dataPath);
Directory.CreateDirectory(playerDataPath);

// set the config file path
// we prefer xml over json because it is easier to edit for the user..
// most users are not experienced with json format. xml is more familiar.
// the class config are fine as json as they really don't need to be edited by the user.
// any issues serializing to xml can be fixed by implementing a serializable version of
// what doesnt have ISerializable implemented.
string configFile = Path.Combine(StoragePath, "RPGPluginConfig.xml");

if (!File.Exists(configFile))
Expand All @@ -179,7 +171,6 @@ private void SetupConfig()
catch (Exception e)
{
Log.Warn(e);

}

if (_config?.Data == null)
Expand All @@ -203,24 +194,40 @@ private void SetupConfig()
{
Log.Warn(e);
}
Save();
await Save();
}
}
}



public void Save()
public Task Save()
{
try
{
_config.Save();
Log.Info("Main Configuration Saved.");
return Task.CompletedTask;
}
catch (IOException e)
{
Log.Warn(e, "Main Configuration Saved during plugin loading.");
return Task.FromException<IOException>(e);
}
}

private async Task WaitThenSetupClasses()
{
// Had issues were roles were loaded faster than the config was created... causes issues.
await Task.Run(async () =>
{
while (Config == null)
{
// If the config is null, wait a second and try again. Repeat until config is loaded.
Thread.Sleep(1000);
}

await RoleAgent.LoadAllRoles();
});

}
}
}
13 changes: 5 additions & 8 deletions RPGPlugin/RPGPluginCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class RolesCommands : CommandModule

[Command("setrole", "Set your role")]
[Permission(MyPromoteLevel.None)]
public void SetRole(string roleName)
public async void SetRole(string roleName)
{
if (Context.Player == null)
{
Expand All @@ -36,11 +36,8 @@ public void SetRole(string roleName)
}

// Check if the role is valid
if (!Roles.Instance.Config.RegisteredRoles.Any(r => r.Item1.Equals(roleName, StringComparison.OrdinalIgnoreCase)))
if (Roles.Instance.Config.RegisteredRoles.Any(r => r.Item1.Equals(roleName, StringComparison.OrdinalIgnoreCase)))
{

if (roleName != Roles.Instance.Config.RegisteredRoles[index].Item1) continue;

Roles.PlayerManagers[Context.Player.SteamUserId].SetRole(roleName);
await Roles.PlayerManagers[Context.Player.SteamUserId].SavePlayerData();
Context.Respond($"Your role has been updated to [{roleName}]");
Expand Down Expand Up @@ -95,9 +92,9 @@ public void Stats()

StringBuilder reply = new StringBuilder();
reply.AppendLine("*** Information ***");
reply.AppendLine("—————————————————————————————");
reply.AppendLine("—————————————————————————");
reply.AppendLine($"Current Role: {currentPlayerRole}");
reply.AppendLine("—————————————————————————————");
reply.AppendLine("—————————————————————————");
foreach (SerializableTuple<string,string> role in Roles.Instance.Config.RegisteredRoles)
{
if (!Roles.PlayerManagers[Context.Player.SteamUserId]._PlayerData.ClassInfo.ContainsKey(role.Item1))
Expand All @@ -109,7 +106,7 @@ public void Stats()
reply.AppendLine($"{role.Item1}:");
reply.AppendLine($"Current level: {Roles.PlayerManagers[Context.Player.SteamUserId]._PlayerData.ClassInfo[role.Item1].Item1}.");
reply.AppendLine($"Exp needed for next level: {Roles.roles[role.Item1 + "Class"].ExpToLevelUp(Context.Player.SteamUserId).ToString()}.");
reply.AppendLine("—————————————————————————————");
reply.AppendLine("—————————————————————————");
}

Context.Respond(reply.ToString());
Expand Down
49 changes: 20 additions & 29 deletions RPGPlugin/Roles/Behavior/WarriorClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ public class WarriorClass : ClassesBase
{
/// <inheritdoc />
/// Point to your classConfig ExpRatio collection
public override ObservableCollection<KeyValuePair<string, double>> ExpRatio { get; set; } =
new ObservableCollection<KeyValuePair<string, double>>();
public override ObservableCollection<KeyValuePair<string, double>> ExpRatio { get; set; } = new ObservableCollection<KeyValuePair<string, double>>();

//test skill point system
public override ObservableCollection<KeyValuePair<int, int>> SkillPoints { get; set; } =
new ObservableCollection<KeyValuePair<int, int>>();
public override ObservableCollection<KeyValuePair<int, int>> SkillPoints { get; set; } = new ObservableCollection<KeyValuePair<int, int>>();

/// <inheritdoc />
public override void init()
Expand All @@ -47,32 +45,25 @@ private void DamageHandler(object target, ref MyDamageInformation info)
// Deformation damage can be from ramming such as torpedo grids, or a warship hitting another.
// Will do a sample here. Be warned... This requires allot of work and will become a bit long... :)

if (target is MyCubeBlock block)
{
// Get relation between grid and attacker
if (block.IDModule.GetUserRelationToOwner(info.AttackerId) != MyRelationsBetweenPlayerAndBlock.Friends)
if (!(target is MyCubeBlock block)) return;

// Get relation between grid and attacker
if (block.IDModule.GetUserRelationToOwner(info.AttackerId) == MyRelationsBetweenPlayerAndBlock.Friends) return;

if (block.CubeGrid.GridSizeEnum == MyCubeSize.Small)
_ProcessQueue.Enqueue(new ExperienceAction
{
switch (block.CubeGrid.GridSizeEnum)
{
case MyCubeSize.Small:
_ProcessQueue.Enqueue( new ExperienceAction
{
ownerID = info.AttackerId,
subType = "EnemySmallBlock",
amount = info.Amount // This gives points per point of damage.
});
break;
case MyCubeSize.Large:
_ProcessQueue.Enqueue( new ExperienceAction
{
ownerID = info.AttackerId,
subType = "EnemyLargeBlock",
amount = info.Amount // This gives points per point of damage.
});
break;
}
}
}
ownerID = info.AttackerId,
subType = "EnemySmallBlock",
amount = info.Amount // This gives points per point of damage.
});
else if (block.CubeGrid.GridSizeEnum == MyCubeSize.Large)
_ProcessQueue.Enqueue(new ExperienceAction
{
ownerID = info.AttackerId,
subType = "EnemyLargeBlock",
amount = info.Amount // This gives points per point of damage.
});
}

/// <inheritdoc />
Expand Down
25 changes: 22 additions & 3 deletions RPGPlugin/Roles/Config/HunterConfig.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using Newtonsoft.Json;
using RPGPlugin.Utils;
using RPGPlugin.View;

namespace RPGPlugin
{
public sealed class HunterConfig : configBase
{
// Definition of the ExpRatio property, which stores experience point values for individual minerals

/// <inheritdoc />
public override string ViewName { get; } = "Hunter";

/// <inheritdoc />
public override ObservableCollection<KeyValuePair<string, double>> ExpRatio { get; set; } =
new ObservableCollection<KeyValuePair<string, double>>();
Expand All @@ -25,14 +33,25 @@ public override void init()
ExpRatio.Add(new KeyValuePair<string, double>("Spider", 0.0013 ));
ExpRatio.Add(new KeyValuePair<string, double>("SmallBlock", 2 ));
ExpRatio.Add(new KeyValuePair<string, double>("LargeBlock", 10 ));

StaticHelperFunctions.StaThreadWrapper(() =>
{

Roles.Log.Warn($"HunterSTA Thread => {Thread.CurrentThread.ManagedThreadId}");
UserControl classView = new Hunter();
Roles.Instance.classViews.Add("Hunter", classView);

});

}

public override void RegisterClass()
{
// Register Class Info
SerializableTuple<string, string> RoleToRegister = new SerializableTuple<string, string>{Item1 = "Hunter", Item2 = "Specialized in attacking NPC ships and creatures."};

if (!Roles.Instance.Config.RegisteredRoles.Contains(RoleToRegister))
Roles.Instance.Config.RegisteredRoles.Add(RoleToRegister);
if (Roles.Instance.Config.RegisteredRoles.Any(role => role.Item1.Equals(RoleToRegister.Item1, StringComparison.OrdinalIgnoreCase))) return ;
Roles.Instance.Config.RegisteredRoles.Add(RoleToRegister);
Roles.Log.Warn($"Registered New Class: {RoleToRegister.Item1}");
}

public override void LoadConfig()
Expand Down
Loading