Slight refractor

- Added balls and butt options
- Renamed Resources to Data
- Addons is now Universal (although probably going to be renamed to Common next)
- Bits was renamed Genitals
- Genital selection uses enums
This commit is contained in:
Tony Bark 2026-05-15 13:39:25 -04:00
parent 15cdb3f3d3
commit 247b738ecc
17 changed files with 268 additions and 92 deletions

View file

@ -43,6 +43,20 @@ dotnet_naming_rule.consts_must_be_all_caps.severity = warning
dotnet_naming_rule.consts_must_be_all_caps.symbols = const_fields
dotnet_naming_rule.consts_must_be_all_caps.style = all_caps
# Turn off the naming style that enforces an underscore prefix for private fields
dotnet_naming_style.underscore_prefix_style.capitalization = camel_case
dotnet_naming_style.underscore_prefix_style.required_prefix = _
# Remove the rule that ties the naming style to private fields
dotnet_naming_rule.private_fields_underscore_rule.severity = none
dotnet_naming_rule.private_fields_underscore_rule.symbols = private_fields
dotnet_naming_rule.private_fields_underscore_rule.style = underscore_prefix_style
# Symbol group for private fields (so the rule can be disabled)
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
# Formatting
csharp_new_line_before_open_brace = all
csharp_indent_case_contents = true

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View file

@ -1,17 +0,0 @@
namespace CyberBits;
public record Bits(
[property: JsonPropertyName("image")]
string Image,
[property: JsonPropertyName("feat")]
string Feat,
[property: JsonPropertyName("model")]
string[] Model,
[property: JsonPropertyName("style")]
string[] Style
);
public record Addon(
[property: JsonPropertyName("cyberware")]
string[] Cyberware
);

View file

@ -9,9 +9,15 @@
</PropertyGroup>
<ItemGroup>
<AvaloniaResource Include="Resources\addons.json" />
<AvaloniaResource Include="Resources\cock.json" />
<AvaloniaResource Include="Resources\pussy.json" />
<None Include="Data\universal.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Data\cock.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Data\pussy.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Folder Include="Models\"/>
<AvaloniaResource Include="Assets\**"/>
</ItemGroup>

21
CyberBits/Data/cock.json Normal file
View file

@ -0,0 +1,21 @@
{
"image": "avares://CyberBits/Assets/cock.jpg",
"feat": "Aim Piss",
"model": [
"Au Natural",
"Les Americaines",
"La Grand Chungus",
"Veini Vici",
"Das Banane",
"The Ace Custom"
],
"extra": [
"Hairy",
"Dangly",
"Asymmetrical",
"Bulbous",
"Doubled",
"Wrinkly",
"Cyber"
]
}

20
CyberBits/Data/pussy.json Normal file
View file

@ -0,0 +1,20 @@
{
"image": "avares://CyberBits/Assets/pussy.jpg",
"feat": "Boom of the Mother Godness",
"model": [
"The Shy Sharon",
"The Proud Priscilla",
"The Matronly Miriam",
"The Stretchy Sandra",
"The Outer Olivia"
],
"extra": [
"Huge",
"Hooded",
"Bright",
"Shifted",
"Hard",
"Expansive",
"Cyber"
]
}

View file

@ -0,0 +1,39 @@
{
"aesthetic": [
"Bioware",
"Cyberware",
"Roboware",
"Holoware"
],
"cyberware": [
"Piercings",
"Datajack",
"Censor Field",
"Laser Sight",
"AI-Controlled Booster Module",
"Second Bladder",
"Map Hack",
"Monowire Blade",
"Projectile Launcher"
],
"pubes": [
"The Baldie",
"The Peach",
"The Landing Strip",
"The Peek-a-Boo",
"The Rectangle",
"The Bar Code",
"The Heart",
"The Lighting Bolt",
"The Neat Triangle",
"The Forest",
"The Jungle",
"The Breath of the Wild"
],
"butt":
[
"Big",
"Round",
"Firm"
]
}

8
CyberBits/DataFiles.cs Normal file
View file

@ -0,0 +1,8 @@
namespace CyberBits;
public struct DataFiles
{
public const string COCK_JSON = "/Data/cock.json";
public const string PUSSY_JSON = "Data/pussy.json";
public const string UNIVERSAL_JSON = "Data/universal.json";
}

33
CyberBits/Genitals.cs Normal file
View file

@ -0,0 +1,33 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace CyberBits;
public enum Genitals
{
COCK,
PUSSY
}
public record GenitalModel(
[property: JsonPropertyName("image")]
string Image,
[property: JsonPropertyName("feat")]
string Feat,
[property: JsonPropertyName("model")]
string[] Model,
[property: JsonPropertyName("aesthetic")]
string[] Aesthetic,
[property: JsonPropertyName("extra")]
string[] Extra // Balls or Clits
);
public record UniversalModel(
[property: JsonPropertyName("aesthetic")]
string[] Aesthetic,
[property: JsonPropertyName("cyberware")]
string[] Cyberware,
[property: JsonPropertyName("pubes")]
string[] Pubes,
[property: JsonPropertyName("butt")]
string[] Butt
);

View file

@ -16,7 +16,7 @@ public static class ImageHelper
return new Bitmap(AssetLoader.Open(resourceUri));
}
public static async Task<Bitmap?> LoadFromWeb(Uri url)
public static async Task<Bitmap?> LoadFromWebAsync(Uri url)
{
try
{

View file

@ -1,8 +0,0 @@
namespace CyberBits;
public struct ResourceFiles
{
public const string COCK_JSON = "Resources/cock.json";
public const string PUSSY_JSON = "Resources/pussy.json";
public const string ADDONS_JSON = "Resources/addons.json";
}

View file

@ -1,6 +0,0 @@
{
"cyberware": [
"Piercings",
"Datajack"
]
}

View file

@ -1,16 +0,0 @@
{
"image": "avares://CyberBits/Assets/cock.jpg",
"feat": "Aim Piss",
"model": [
"Au Natural",
"Les Americaines"
],
"style": [
"Bioware",
"Cyberware"
],
"cyberware": [
"Piercings",
"Datajack"
]
}

View file

@ -1,12 +0,0 @@
{
"image": "avares://CyberBits/Assets/pussy.jpg",
"feat": "Boom of the Mother Godness",
"model": [
"Au Natural",
"Les Americaines"
],
"style": [
"Bioware",
"Cyberware"
]
}

View file

@ -1,11 +1,12 @@
using System.Collections.ObjectModel;
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
namespace CyberBits.ViewModels;
public partial class ViewModelBase : ObservableObject
{
public ObservableCollection<string> GenitalsList { get; } = ["Cock", "Pussy"];
public Genitals[] GenitalOptions { get; } = Enum.GetValues<Genitals>();
public ObservableCollection<string> ModelsList { get; } =
[
@ -54,7 +55,25 @@ public partial class ViewModelBase : ObservableObject
"The Breath of the Wild"
];
[ObservableProperty] private string? _selectedBits;
public ObservableCollection<string> ExtrasList { get; } =
[
"Hairy",
"Dangly",
"Asymmetrical",
"Bulbous",
"Doubled",
"Wrinkly",
"Cyber"
];
public ObservableCollection<string> ButtsList { get; } =
[
"Big",
"Round",
"Firm"
];
[ObservableProperty] private Genitals _selectedBits = Genitals.COCK;
[ObservableProperty] private string? _selectedModels;
@ -63,4 +82,8 @@ public partial class ViewModelBase : ObservableObject
[ObservableProperty] private string? _selectedCyberware;
[ObservableProperty] private string? _selectedPubes;
[ObservableProperty] private string? _selectedExtras;
[ObservableProperty] private string? _selectedButt;
}

View file

@ -3,8 +3,8 @@
xmlns:vm="using:CyberBits.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="720" d:DesignHeight="430"
Width="720" Height="430" CanResize="False"
mc:Ignorable="d" d:DesignWidth="700" d:DesignHeight="520"
Width="700" Height="520" CanResize="False"
ExtendClientAreaToDecorationsHint="True"
x:Class="CyberBits.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
@ -25,49 +25,72 @@
Text="CyberBits" >
</TextBlock>
</Border>
<Grid ColumnDefinitions="*,*">
<Grid ColumnDefinitions="*,*" HorizontalAlignment="Center">
<Image x:Name="BitsImage" Grid.Column="0" Source="avares://CyberBits/Assets/cock.jpg" />
<GridSplitter Grid.Column="1" ResizeDirection="Columns"/>
<StackPanel Grid.Column="1">
<ComboBox ItemsSource="{Binding GenitalsList}"
<Grid ColumnDefinitions="160,160">
<GridSplitter ResizeDirection="Columns"/>
<StackPanel Grid.Column="0" >
<ComboBox ItemsSource="{Binding GenitalOptions}"
SelectedItem="{Binding SelectedBits}"
PlaceholderText="Genitals"
Width="100"
Width="120"
HorizontalContentAlignment="Center"
SelectedValue="0"
x:Name="BitSelection"
HorizontalAlignment="Center"
SelectionChanged="SelectedBitsControl_OnSelectionChanged"
Margin="5"/>
<Border Height="10" />
<Grid ColumnDefinitions="*,*">
<GridSplitter ResizeDirection="Columns"/>
<StackPanel Grid.Column="0" >
<TextBlock Text="Models" />
<ListBox ItemsSource="{Binding ModelsList}"
SelectedItem="{Binding SelectedModels}"
Name="ModelItems"
Margin="5"
Height="110"/>
<Border Height="10" />
<TextBlock Text="Pubes" />
<TextBlock Text="Pubes" HorizontalAlignment="Center" />
<ListBox ItemsSource="{Binding PubesList}"
SelectedItem="{Binding SelectedPubes}"
Name="PubesItems"
Margin="5"
Height="110"/>
<TextBlock Name="ExtrasText" Text="Balls" HorizontalAlignment="Center" />
<ListBox
ItemsSource="{Binding ExtrasList}"
SelectedItem="{Binding SelectedExtras}"
Name="ExtraItems"
Margin="5"
Height="110"
/>
</StackPanel>
<GridSplitter Grid.Column="1" ResizeDirection="Columns"/>
<StackPanel Grid.Column="1">
<TextBlock Text="Aesthetics" />
<Button Background="Transparent"
HorizontalAlignment="Right"
Width="100"
Height="40">
<Image Source="avares://CyberBits/Assets/game_die.png" />
</Button>
<TextBlock Text="Aesthetics" HorizontalAlignment="Center" />
<ListBox ItemsSource="{Binding AestheticsList}"
SelectedItem="{Binding SelectedAesthetics}"
Name="AestheticsItems"
Margin="5"
Height="110"/>
<Border Height="10" />
<TextBlock Text="CyberwareList" />
<TextBlock Text="Cyberware" HorizontalAlignment="Center" />
<ListBox ItemsSource="{Binding CyberwareList}"
SelectedItem="{Binding SelectedCyberware}"
Name="CyberwareItems"
Margin="5"
Height="110" />
<TextBlock Text="Butt" HorizontalAlignment="Center" />
<ListBox ItemsSource="{Binding ButtsList}"
SelectedItem="{Binding SelectedButt}"
Name="ButtOptions"
Margin="5"
Height="110"
/>
</StackPanel>
</Grid>
</StackPanel>

View file

@ -1,29 +1,77 @@
using System;
using System.IO;
using System.Reflection;
using System.Text.Json;
using Avalonia.Controls;
namespace CyberBits.Views;
public partial class MainWindow : Window
{
string? AppPath => Path.GetDirectoryName(Assembly.GetAssembly(typeof(MainWindow))?.Location);
public MainWindow()
{
InitializeComponent();
VersionBox.Text = $"v{AppConsts.VERSION}";
try
{
var univieralFile = File.ReadAllText($"{AppPath}//{DataFiles.UNIVERSAL_JSON}");
var univieralData = JsonSerializer.Deserialize<UniversalModel>(univieralFile);
PubesItems.ItemsSource = univieralData?.Pubes;
CyberwareItems.ItemsSource = univieralData?.Cyberware;
AestheticsItems.ItemsSource = univieralData?.Aesthetic;
ButtOptions.ItemsSource = univieralData?.Butt;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
#if DEBUG
VersionBox.Text = $"{AppConsts.VERSION}-{ThisAssembly.Git.Commit}";
#else
VersionBox.Text = AppConsts.VERSION;
#endif
}
void GenitalSwap(string image, string data)
{
try
{
var genitalFile = File.ReadAllText($"{AppPath}//{data}");
var genitalData = JsonSerializer.Deserialize<GenitalModel>(genitalFile);
var genitalImage = ImageHelper.LoadFromResource(new Uri(image));
BitsImage.Source = genitalImage;
ModelItems.ItemsSource = genitalData?.Model;
ExtraItems.ItemsSource = genitalData?.Extra;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private void SelectedBitsControl_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
var appPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(MainWindow))?.Location);
switch (BitSelection.SelectionBoxItem)
{
case "Pussy":
var pussy = ImageHelper.LoadFromResource(new Uri("avares://CyberBits/Assets/pussy.jpg"));
BitsImage.Source = pussy;
case Genitals.PUSSY:
GenitalSwap("avares://CyberBits/Assets/pussy.jpg", DataFiles.PUSSY_JSON);
ExtrasText.Text = "Clits";
break;
case "Cock":
var cock = ImageHelper.LoadFromResource(new Uri("avares://CyberBits/Assets/cock.jpg"));
BitsImage.Source = cock;
case Genitals.COCK:
GenitalSwap("avares://CyberBits/Assets/cock.jpg", DataFiles.COCK_JSON);
ExtrasText.Text = "Balls";
break;
}
}