Added combat level calculator with player stat lookup.

This commit is contained in:
2025-05-23 11:22:38 -04:00
parent 1baaf6551d
commit f62aeac08f
7 changed files with 358 additions and 1 deletions

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace osrs_toolbox
{
public abstract class CombatLevelModel : ModelBase
{
private string _userName;
private int _attack;
private int _strength;
private int _hitpoints;
private int _defense;
private int _ranged;
private int _magic;
private int _prayer;
private ICommand _loadPlayer;
public string UserName
{
get { return _userName; }
set { SetProperty(ref _userName, value, nameof(UserName)); }
}
public int Attack
{
get { return _attack; }
set
{
SetProperty(ref _attack, value, nameof(Attack));
UpdateOutput();
}
}
public int Strength
{
get { return _strength; }
set
{
SetProperty(ref _strength, value, nameof(Strength));
UpdateOutput();
}
}
public int Hitpoints
{
get { return _hitpoints; }
set
{
SetProperty(ref _hitpoints, value, nameof(Hitpoints));
UpdateOutput();
}
}
public int Defense
{
get { return _defense; }
set
{
SetProperty(ref _defense, value, nameof(Defense));
UpdateOutput();
}
}
public int Ranged
{
get { return _ranged; }
set
{
SetProperty(ref _ranged, value, nameof(Ranged));
UpdateOutput();
}
}
public int Magic
{
get { return _magic; }
set
{
SetProperty(ref _magic, value, nameof(Magic));
UpdateOutput();
}
}
public int Prayer
{
get { return _prayer; }
set
{
SetProperty(ref _prayer, value, nameof(Prayer));
UpdateOutput();
}
}
public ICommand LoadPlayer
{
get { return _loadPlayer; }
set { SetProperty(ref _loadPlayer, value, nameof(LoadPlayer)); }
}
private void UpdateOutput()
{
OnPropertyChanged(nameof(CombatLevel));
OnPropertyChanged(nameof(NextLevel));
OnPropertyChanged(nameof(NeededAttack));
OnPropertyChanged(nameof(NeededStrength));
OnPropertyChanged(nameof(NeededDefense));
OnPropertyChanged(nameof(NeededHitpoints));
OnPropertyChanged(nameof(NeededRanged));
OnPropertyChanged(nameof(NeededMagic));
OnPropertyChanged(nameof(NeededPrayer));
}
public double CombatLevel => Math.Floor(0.25d * (Defense + Hitpoints + Math.Floor(Prayer / 2d)) + (0.325 * Math.Max(Math.Max(Attack + Strength, Ranged * 1.5d), Magic * 1.5d)));
public double NextLevel => Math.Min(126, CombatLevel + 1);
public string NeededAttack
{
get
{
double AttackCalc = Math.Ceiling((NextLevel - (0.25d * Defense) - (0.25d * Hitpoints) - (0.25d * Math.Floor(Prayer / 2d)) - (0.325 * Strength)) / 0.325d) - Attack;
if (AttackCalc + Attack > 99) return "-";
else return AttackCalc.ToString();
}
}
public string NeededStrength
{
get
{
double StrengthCalc = Math.Ceiling((NextLevel - (0.25d * Defense) - (0.25d * Hitpoints) - (0.25d * Math.Floor(Prayer / 2d)) - (0.325 * Attack)) / 0.325d) - Strength;
if (StrengthCalc + Strength > 99) return "-";
else return StrengthCalc.ToString();
}
}
public string NeededDefense
{
get
{
double DefenseCalc = Math.Ceiling((NextLevel - (0.25 * Hitpoints) - (0.25 * Math.Floor(Prayer / 2d)) - (0.325 * Math.Max(Math.Max(Attack + Strength, Ranged * 1.5d), Magic * 1.5d))) / 0.25) - Defense;
if (DefenseCalc + Defense > 99) return "-";
else return DefenseCalc.ToString();
}
}
public string NeededHitpoints
{
get
{
double HitpointsCalc = Math.Ceiling((NextLevel - (0.25d * Defense) - (0.25d * Math.Floor(Prayer / 2d)) - (0.325 * Math.Max(Math.Max(Attack + Strength, Ranged * 1.5d), Magic * 1.5d))) / 0.25d) - Hitpoints;
if (HitpointsCalc + Hitpoints > 99) return "-";
else return HitpointsCalc.ToString();
}
}
public string NeededRanged
{
get
{
double RangedCalc = Math.Ceiling((NextLevel - (0.25 * (Defense + Hitpoints + Math.Floor(Prayer / 2d)))) / 0.4875d) - Ranged;
if (RangedCalc + Ranged > 99) return "-";
else return RangedCalc.ToString();
}
}
public string NeededMagic
{
get
{
double MagicCalc = Math.Ceiling((NextLevel - (0.25 * (Defense + Hitpoints + Math.Floor(Prayer / 2d)))) / 0.4875d) - Magic;
if (MagicCalc + Magic > 99) return "-";
else return MagicCalc.ToString();
}
}
public string NeededPrayer
{
get
{
double PrayerCalc = Math.Ceiling((NextLevel - (0.25d * Hitpoints) - (0.25d * Defense) - (0.325 * Math.Max(Math.Max(Attack + Strength, Ranged * 1.5d), Magic * 1.5d))) / 0.125d) - Prayer;
if (PrayerCalc + Prayer > 99) return "-";
else return PrayerCalc.ToString();
}
}
}
}

View File

@@ -13,6 +13,7 @@ namespace osrs_toolbox
{
private ICommand _openCompetitionOverlaySettings;
private ICommand _openDropChanceCalculator;
private ICommand _openCombatLevelCalculator;
public ICommand OpenCompetitionOverlaySettings
{
@@ -25,5 +26,11 @@ namespace osrs_toolbox
get { return _openDropChanceCalculator; }
set { SetProperty(ref _openDropChanceCalculator, value, nameof(OpenDropChanceCalculator)); }
}
public ICommand OpenCombatLevelCalculator
{
get { return _openCombatLevelCalculator; }
set { SetProperty(ref _openCombatLevelCalculator, value, nameof(OpenCombatLevelCalculator)); }
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace osrs_toolbox
{
public class CombatLevelViewModel : CombatLevelModel
{
public CombatLevelViewModel()
{
InitializeVariables();
InitializeCommands();
}
private void InitializeVariables()
{
UserName = string.Empty;
Attack = 1;
Strength = 1;
Defense = 1;
Hitpoints = 10;
Ranged = 1;
Prayer = 1;
Magic = 1;
}
private void InitializeCommands()
{
LoadPlayer = new RelayCommand(DoLoadPlayer);
}
private void DoLoadPlayer(object obj)
{
Player p;
try
{
p = WiseOldMan.GetPlayer(UserName);
}
catch
{
InitializeVariables();
UserName = "User Not Found on Wise Old Man";
return;
}
if (p.latestSnapshot is null)
{
InitializeVariables();
UserName = "User Not Found on Wise Old Man";
return;
}
Attack = p.latestSnapshot.data.skills.attack.level;
Strength = p.latestSnapshot.data.skills.strength.level;
Defense = p.latestSnapshot.data.skills.defence.level;
Hitpoints = p.latestSnapshot.data.skills.hitpoints.level;
Ranged = p.latestSnapshot.data.skills.ranged.level;
Prayer = p.latestSnapshot.data.skills.prayer.level;
Magic = p.latestSnapshot.data.skills.magic.level;
}
}
}

View File

@@ -24,6 +24,7 @@ namespace osrs_toolbox
{
OpenCompetitionOverlaySettings = new RelayCommand(DoOpenCompetitionOverlaySettings);
OpenDropChanceCalculator = new RelayCommand(DoOpenDropChanceCalculator);
OpenCombatLevelCalculator = new RelayCommand(DoOpenCombatLevelCalculator);
}
private void DoOpenCompetitionOverlaySettings(object obj)
@@ -53,5 +54,19 @@ namespace osrs_toolbox
dcv.Show();
}
}
private void DoOpenCombatLevelCalculator(object obj)
{
if (CombatLevelView.Current != null)
{
CombatLevelView.Current.Close();
CombatLevelView.Current = null;
}
else
{
CombatLevelView clv = new CombatLevelView();
clv.Show();
}
}
}
}

View File

@@ -0,0 +1,61 @@
<Window x:Class="osrs_toolbox.CombatLevelView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:osrs_toolbox"
mc:Ignorable="d"
Title="Combat Level Calculator" Height="450" Width="800" SizeToContent="WidthAndHeight" Closed="Window_Closed">
<Window.DataContext>
<local:CombatLevelViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Username:" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3"/>
<Button Command="{Binding LoadPlayer, UpdateSourceTrigger=PropertyChanged}" Content="Load Player" Grid.Column="3" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3" Padding="3"/>
<TextBlock Text="Current Level" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="3"/>
<TextBlock Text="Needed for Next Level" Grid.Column="2" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Attack:" Grid.Column="0" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Strength:" Grid.Column="0" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Defense:" Grid.Column="0" Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Hitpoints:" Grid.Column="0" Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Ranged:" Grid.Column="0" Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Magic:" Grid.Column="0" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Prayer:" Grid.Column="0" Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="Combat Level:" Grid.Column="0" Grid.Row="9" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBox Text="{Binding Attack, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBox Text="{Binding Strength, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBox Text="{Binding Defense, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBox Text="{Binding Hitpoints, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBox Text="{Binding Ranged, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBox Text="{Binding Magic, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBox Text="{Binding Prayer, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="3" Padding="1"/>
<TextBlock Text="{Binding CombatLevel, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="9" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NextLevel, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="9" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededAttack, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededStrength, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededDefense, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededHitpoints, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededRanged, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededMagic, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
<TextBlock Text="{Binding NeededPrayer, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3"/>
</Grid>
</Window>

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace osrs_toolbox
{
/// <summary>
/// Interaction logic for CombatLevelView.xaml
/// </summary>
public partial class CombatLevelView : Window
{
public static CombatLevelView Current;
public CombatLevelView()
{
InitializeComponent();
Current = this;
}
private void Window_Closed(object sender, EventArgs e)
{
Current = null;
}
}
}

View File

@@ -9,8 +9,9 @@
<Window.DataContext>
<local:HomePageViewModel/>
</Window.DataContext>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding OpenCompetitionOverlaySettings, UpdateSourceTrigger=PropertyChanged}" Content="Open Competition Overlay Settings" Margin="3" Padding="3" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button Command="{Binding OpenDropChanceCalculator, UpdateSourceTrigger=PropertyChanged}" Content="Open Drop Chance Calculator" Margin="3" Padding="3" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button Command="{Binding OpenCombatLevelCalculator, UpdateSourceTrigger=PropertyChanged}" Content="Open Combat Level Calculator" Margin="3" Padding="3" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Window>