Resolving problems

This commit is contained in:
Karol Górzyński 2021-01-03 15:54:18 +01:00
commit 883d1835d1
108 changed files with 11887 additions and 174 deletions

View File

@ -1,7 +1,9 @@
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using SessionCompanion.Database.Tables;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -27,8 +29,62 @@ namespace SessionCompanion.Database
public virtual DbSet<Spell> Spells { get; set; }
public virtual DbSet<CharacterSpell> CharacterSpells { get; set; }
public virtual DbSet<CharacterSpellSlots> CharacterSpellSlots { get; set; }
public virtual DbSet<Armor> Armors { get; set; }
public virtual DbSet<CharacterArmor> CharacterArmors { get; set; }
public virtual DbSet<Weapon> Weapons { get; set; }
public virtual DbSet<CharacterWeapon> CharacterWeapons { get; set; }
public virtual DbSet<OtherEquipment> OtherEquipment { get; set; }
public virtual DbSet<CharacterOtherEquipment> CharacterOtherEquipment { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
protected IEnumerable<Weapon> SeedWeapon()
{
const string file = "../SessionCompanion.Database/JsonData/weapons.json";
List<Weapon> weapons = new List<Weapon>();
using (StreamReader reader = new StreamReader(file))
{
var json = reader.ReadToEnd();
dynamic jweapons = JArray.Parse(json);
foreach (dynamic item in jweapons)
weapons.Add(SeedFromJsons.SingleWeaponSeeder(item));
}
return weapons;
}
protected IEnumerable<Armor> SeedArmor()
{
const string file = "../SessionCompanion.Database/JsonData/armors.json";
List<Armor> armors = new List<Armor>();
using (StreamReader reader = new StreamReader(file))
{
var json = reader.ReadToEnd();
dynamic jactions = JArray.Parse(json);
int id = 1;
foreach (dynamic item in jactions)
{
armors.Add(SeedFromJsons.SingleArmorSeeder(item, id));
id++;
}
}
return armors;
}
protected IEnumerable<OtherEquipment> SeedOtherEquipment()
{
const string file = "../SessionCompanion.Database/JsonData/otherEquipments.json";
List<OtherEquipment> otherEquipment = new List<OtherEquipment>();
using (StreamReader reader = new StreamReader(file))
{
var json = reader.ReadToEnd();
dynamic jactions = JArray.Parse(json);
int id = 1;
foreach (dynamic item in jactions)
{
otherEquipment.Add(SeedFromJsons.SingleOtherEquipmentSeeder(item, id));
id++;
}
}
return otherEquipment;
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
@ -40,6 +96,12 @@ namespace SessionCompanion.Database
builder.Entity<Background>().HasData(SeedData.SeedBackground());
builder.Entity<Biography>().HasData(SeedData.SeedBiography());
builder.Entity<Statistics>().HasData(SeedData.SeedStatistics());
builder.Entity<Weapon>().HasData(SeedWeapon());
builder.Entity<Armor>().HasData(SeedArmor());
builder.Entity<OtherEquipment>().HasData(SeedOtherEquipment());
builder.Entity<CharacterWeapon>().HasData(SeedData.SeedCharacterWeapon());
builder.Entity<CharacterArmor>().HasData(SeedData.SeedCharacterArmor());
builder.Entity<CharacterOtherEquipment>().HasData(SeedData.SeedCharacterOtherEquipment());
}
}
}

View File

@ -0,0 +1,236 @@
[
{
"index": 38,
"name": "Padded",
"equipment_category": "Armor",
"armor_category": "Light",
"armor_class": {
"base": 11,
"dex_bonus": true,
"max_bonus": null
},
"str_minimum": 0,
"stealth_disadvantage": true,
"weight": 8,
"cost": {
"quantity": 5,
"unit": "gp"
}
},
{
"index": 39,
"name": "Leather",
"equipment_category": "Armor",
"armor_category": "Light",
"armor_class": {
"base": 11,
"dex_bonus": true,
"max_bonus": null
},
"str_minimum": 0,
"stealth_disadvantage": false,
"weight": 10,
"cost": {
"quantity": 10,
"unit": "gp"
}
},
{
"index": 40,
"name": "Studded Leather",
"equipment_category": "Armor",
"armor_category": "Light",
"armor_class": {
"base": 12,
"dex_bonus": true,
"max_bonus": null
},
"str_minimum": 0,
"stealth_disadvantage": false,
"weight": 13,
"cost": {
"quantity": 45,
"unit": "gp"
}
},
{
"index": 41,
"name": "Hide",
"equipment_category": "Armor",
"armor_category": "Medium",
"armor_class": {
"base": 12,
"dex_bonus": true,
"max_bonus": 2
},
"str_minimum": 0,
"stealth_disadvantage": false,
"weight": 12,
"cost": {
"quantity": 10,
"unit": "gp"
}
},
{
"index": 42,
"name": "Chain Shirt",
"equipment_category": "Armor",
"armor_category": "Medium",
"armor_class": {
"base": 13,
"dex_bonus": true,
"max_bonus": 2
},
"str_minimum": 0,
"stealth_disadvantage": false,
"weight": 20,
"cost": {
"quantity": 50,
"unit": "gp"
}
},
{
"index": 43,
"name": "Scale Mail",
"equipment_category": "Armor",
"armor_category": "Medium",
"armor_class": {
"base": 14,
"dex_bonus": true,
"max_bonus": 2
},
"str_minimum": 0,
"stealth_disadvantage": true,
"weight": 45,
"cost": {
"quantity": 50,
"unit": "gp"
}
},
{
"index": 44,
"name": "Breastplate",
"equipment_category": "Armor",
"armor_category": "Medium",
"armor_class": {
"base": 14,
"dex_bonus": true,
"max_bonus": 2
},
"str_minimum": 0,
"stealth_disadvantage": false,
"weight": 20,
"cost": {
"quantity": 400,
"unit": "gp"
}
},
{
"index": 45,
"name": "Half Plate",
"equipment_category": "Armor",
"armor_category": "Medium",
"armor_class": {
"base": 15,
"dex_bonus": true,
"max_bonus": 2
},
"str_minimum": 0,
"stealth_disadvantage": true,
"weight": 40,
"cost": {
"quantity": 750,
"unit": "gp"
}
},
{
"index": 46,
"name": "Ring Mail",
"equipment_category": "Armor",
"armor_category": "Heavy",
"armor_class": {
"base": 14,
"dex_bonus": false,
"max_bonus": null
},
"str_minimum": 0,
"stealth_disadvantage": true,
"weight": 40,
"cost": {
"quantity": 30,
"unit": "gp"
}
},
{
"index": 47,
"name": "Chain Mail",
"equipment_category": "Armor",
"armor_category": "Heavy",
"armor_class": {
"base": 16,
"dex_bonus": false,
"max_bonus": null
},
"str_minimum": 13,
"stealth_disadvantage": true,
"weight": 55,
"cost": {
"quantity": 75,
"unit": "gp"
}
},
{
"index": 48,
"name": "Splint",
"equipment_category": "Armor",
"armor_category": "Heavy",
"armor_class": {
"base": 17,
"dex_bonus": false,
"max_bonus": null
},
"str_minimum": 15,
"stealth_disadvantage": true,
"weight": 60,
"cost": {
"quantity": 200,
"unit": "gp"
}
},
{
"index": 49,
"name": "Plate",
"equipment_category": "Armor",
"armor_category": "Heavy",
"armor_class": {
"base": 18,
"dex_bonus": false,
"max_bonus": null
},
"str_minimum": 15,
"stealth_disadvantage": true,
"weight": 65,
"cost": {
"quantity": 1500,
"unit": "gp"
}
},
{
"index": 50,
"name": "Shield",
"equipment_category": "Armor",
"armor_category": "Shield",
"armor_class": {
"base": 2,
"dex_bonus": false,
"max_bonus": null
},
"str_minimum": 0,
"stealth_disadvantage": false,
"weight": 6,
"cost": {
"quantity": 10,
"unit": "gp"
}
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,838 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SessionCompanion.Database;
namespace SessionCompanion.Database.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20201228114303_Class name fix")]
partial class Classnamefix
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.UseIdentityColumns()
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.0");
modelBuilder.Entity("SessionCompanion.Database.Tables.Alignment", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.HasKey("Id");
b.ToTable("Alignments");
b.HasData(
new
{
Id = 1
},
new
{
Id = 2
},
new
{
Id = 3
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Background", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.HasKey("Id");
b.ToTable("Backgrounds");
b.HasData(
new
{
Id = 1
},
new
{
Id = 2
},
new
{
Id = 3
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Biography", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("AlignmentId")
.HasColumnType("int");
b.Property<int>("BackgroundId")
.HasColumnType("int");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("ClassId")
.HasColumnType("int");
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.Property<int>("RaceId")
.HasColumnType("int");
b.Property<string>("Sex")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("AlignmentId");
b.HasIndex("BackgroundId");
b.HasIndex("CharacterId")
.IsUnique();
b.HasIndex("ClassId");
b.HasIndex("RaceId");
b.ToTable("Biographies");
b.HasData(
new
{
Id = 1,
AlignmentId = 1,
BackgroundId = 1,
CharacterId = 1,
ClassId = 1,
Name = "Bob",
RaceId = 1,
Sex = "Male"
},
new
{
Id = 2,
AlignmentId = 2,
BackgroundId = 2,
CharacterId = 2,
ClassId = 2,
Name = "Queen Daenerys Stormborn of the House Targaryen, the First of Her Name, Queen of the Andals, the Rhoynar and the First Men, Lady of the Seven Kingdoms and Protector of the Realm, Lady of Dragonstone, Queen of Meereen, Khaleesi of the Great Grass Sea, the Unburnt, Breaker of Chains and Mother of Dragons.",
RaceId = 2,
Sex = "Female"
},
new
{
Id = 3,
AlignmentId = 3,
BackgroundId = 3,
CharacterId = 3,
ClassId = 3,
Name = "Gandalf the White",
RaceId = 3,
Sex = "Both"
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Character", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Characters");
b.HasData(
new
{
Id = 1,
UserId = 1
},
new
{
Id = 2,
UserId = 2
},
new
{
Id = 3,
UserId = 3
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Charisma", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<bool>("CanDeception")
.HasColumnType("bit");
b.Property<bool>("CanIntimidation")
.HasColumnType("bit");
b.Property<bool>("CanPerformance")
.HasColumnType("bit");
b.Property<bool>("CanPersuasion")
.HasColumnType("bit");
b.Property<bool>("CanSaveThrows")
.HasColumnType("bit");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("Deception")
.HasColumnType("int");
b.Property<int>("Intimidation")
.HasColumnType("int");
b.Property<int>("Modification")
.HasColumnType("int");
b.Property<int>("Performance")
.HasColumnType("int");
b.Property<int>("Persuasion")
.HasColumnType("int");
b.Property<int>("SavingThrows")
.HasColumnType("int");
b.Property<int>("Value")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Charismas");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Class", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Classes");
b.HasData(
new
{
Id = 1,
Name = "Fighter"
},
new
{
Id = 2,
Name = "Paladin"
},
new
{
Id = 3,
Name = "Cleric"
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Constitution", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<bool>("CanSaveThrows")
.HasColumnType("bit");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("Modification")
.HasColumnType("int");
b.Property<int>("SavingThrows")
.HasColumnType("int");
b.Property<int>("Value")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Constitutions");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Dexterity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("Acrobatics")
.HasColumnType("int");
b.Property<bool>("CanAcrobatics")
.HasColumnType("bit");
b.Property<bool>("CanSaveThrows")
.HasColumnType("bit");
b.Property<bool>("CanSleightOfHand")
.HasColumnType("bit");
b.Property<bool>("CanStealth")
.HasColumnType("bit");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("Modification")
.HasColumnType("int");
b.Property<int>("SavingThrows")
.HasColumnType("int");
b.Property<int>("SleightOfHand")
.HasColumnType("int");
b.Property<int>("Stealth")
.HasColumnType("int");
b.Property<int>("Value")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Dexterities");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Intelligence", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("Arcana")
.HasColumnType("int");
b.Property<bool>("CanArcana")
.HasColumnType("bit");
b.Property<bool>("CanHistory")
.HasColumnType("bit");
b.Property<bool>("CanInvestigation")
.HasColumnType("bit");
b.Property<bool>("CanNature")
.HasColumnType("bit");
b.Property<bool>("CanReligion")
.HasColumnType("bit");
b.Property<bool>("CanSaveThrows")
.HasColumnType("bit");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("History")
.HasColumnType("int");
b.Property<int>("Investigation")
.HasColumnType("int");
b.Property<int>("Modification")
.HasColumnType("int");
b.Property<int>("Nature")
.HasColumnType("int");
b.Property<int>("Religion")
.HasColumnType("int");
b.Property<int>("SavingThrows")
.HasColumnType("int");
b.Property<int>("Value")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Intelligences");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Race", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Races");
b.HasData(
new
{
Id = 1,
Name = "Human"
},
new
{
Id = 2,
Name = "Dwarf"
},
new
{
Id = 3,
Name = "Elf"
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Statistics", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("ArmorClass")
.HasColumnType("int");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("CurrentHealthPoints")
.HasColumnType("int");
b.Property<int>("ExperiencePoints")
.HasColumnType("int");
b.Property<int>("HealthPoints")
.HasColumnType("int");
b.Property<int>("Initiative")
.HasColumnType("int");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("Proficiency")
.HasColumnType("int");
b.Property<int>("Speed")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Statistics");
b.HasData(
new
{
Id = 1,
ArmorClass = 9,
CharacterId = 1,
CurrentHealthPoints = 18,
ExperiencePoints = 2,
HealthPoints = 20,
Initiative = 12,
Level = 1,
Proficiency = 1,
Speed = 5
},
new
{
Id = 2,
ArmorClass = 12,
CharacterId = 2,
CurrentHealthPoints = 26,
ExperiencePoints = 0,
HealthPoints = 26,
Initiative = 7,
Level = 1,
Proficiency = 1,
Speed = 10
},
new
{
Id = 3,
ArmorClass = 2,
CharacterId = 3,
CurrentHealthPoints = 7,
ExperiencePoints = 24,
HealthPoints = 7,
Initiative = 18,
Level = 1,
Proficiency = 2,
Speed = 15
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Strength", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("Athletics")
.HasColumnType("int");
b.Property<bool>("CanAthletics")
.HasColumnType("bit");
b.Property<bool>("CanSaveThrows")
.HasColumnType("bit");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("Modification")
.HasColumnType("int");
b.Property<int>("SavingThrows")
.HasColumnType("int");
b.Property<int>("Value")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Strengths");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<string>("Password")
.HasColumnType("nvarchar(max)");
b.Property<string>("Username")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Users");
b.HasData(
new
{
Id = 1,
Password = "123",
Username = "Morwiec"
},
new
{
Id = 2,
Password = "123",
Username = "Cichoklepiec"
},
new
{
Id = 3,
Password = "123",
Username = "Ruletka"
});
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Wisdom", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.UseIdentityColumn();
b.Property<int>("AnimalHandling")
.HasColumnType("int");
b.Property<bool>("CanAnimalHandling")
.HasColumnType("bit");
b.Property<bool>("CanInsight")
.HasColumnType("bit");
b.Property<bool>("CanMedicine")
.HasColumnType("bit");
b.Property<bool>("CanPerception")
.HasColumnType("bit");
b.Property<bool>("CanSaveThrows")
.HasColumnType("bit");
b.Property<bool>("CanSurvival")
.HasColumnType("bit");
b.Property<int>("CharacterId")
.HasColumnType("int");
b.Property<int>("Insight")
.HasColumnType("int");
b.Property<int>("Medicine")
.HasColumnType("int");
b.Property<int>("Modification")
.HasColumnType("int");
b.Property<int>("Perception")
.HasColumnType("int");
b.Property<int>("SavingThrows")
.HasColumnType("int");
b.Property<int>("Survival")
.HasColumnType("int");
b.Property<int>("Value")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CharacterId")
.IsUnique();
b.ToTable("Wisdoms");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Biography", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Alignment", "Alignment")
.WithMany("Biography")
.HasForeignKey("AlignmentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SessionCompanion.Database.Tables.Background", "Background")
.WithMany("Biography")
.HasForeignKey("BackgroundId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Biography")
.HasForeignKey("SessionCompanion.Database.Tables.Biography", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SessionCompanion.Database.Tables.Class", "Class")
.WithMany("Biography")
.HasForeignKey("ClassId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SessionCompanion.Database.Tables.Race", "Race")
.WithMany("Biography")
.HasForeignKey("RaceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Alignment");
b.Navigation("Background");
b.Navigation("Character");
b.Navigation("Class");
b.Navigation("Race");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Character", b =>
{
b.HasOne("SessionCompanion.Database.Tables.User", "User")
.WithMany("Character")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Charisma", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Charisma")
.HasForeignKey("SessionCompanion.Database.Tables.Charisma", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Constitution", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Constitution")
.HasForeignKey("SessionCompanion.Database.Tables.Constitution", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Dexterity", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Dexterity")
.HasForeignKey("SessionCompanion.Database.Tables.Dexterity", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Intelligence", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Intelligence")
.HasForeignKey("SessionCompanion.Database.Tables.Intelligence", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Statistics", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Statistics")
.HasForeignKey("SessionCompanion.Database.Tables.Statistics", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Strength", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Strength")
.HasForeignKey("SessionCompanion.Database.Tables.Strength", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Wisdom", b =>
{
b.HasOne("SessionCompanion.Database.Tables.Character", "Character")
.WithOne("Wisdom")
.HasForeignKey("SessionCompanion.Database.Tables.Wisdom", "CharacterId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Character");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Alignment", b =>
{
b.Navigation("Biography");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Background", b =>
{
b.Navigation("Biography");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Character", b =>
{
b.Navigation("Biography");
b.Navigation("Charisma");
b.Navigation("Constitution");
b.Navigation("Dexterity");
b.Navigation("Intelligence");
b.Navigation("Statistics");
b.Navigation("Strength");
b.Navigation("Wisdom");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Class", b =>
{
b.Navigation("Biography");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.Race", b =>
{
b.Navigation("Biography");
});
modelBuilder.Entity("SessionCompanion.Database.Tables.User", b =>
{
b.Navigation("Character");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,55 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SessionCompanion.Database.Migrations
{
public partial class Classnamefix : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Classes",
keyColumn: "Id",
keyValue: 1,
column: "Name",
value: "Fighter");
migrationBuilder.UpdateData(
table: "Classes",
keyColumn: "Id",
keyValue: 2,
column: "Name",
value: "Paladin");
migrationBuilder.UpdateData(
table: "Classes",
keyColumn: "Id",
keyValue: 3,
column: "Name",
value: "Cleric");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Classes",
keyColumn: "Id",
keyValue: 1,
column: "Name",
value: "Warrior");
migrationBuilder.UpdateData(
table: "Classes",
keyColumn: "Id",
keyValue: 2,
column: "Name",
value: "Knight");
migrationBuilder.UpdateData(
table: "Classes",
keyColumn: "Id",
keyValue: 3,
column: "Name",
value: "Priest");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,480 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SessionCompanion.Database.Migrations
{
public partial class weaponsadded : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Armors",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
Category = table.Column<string>(type: "nvarchar(max)", nullable: true),
ArmorClassBase = table.Column<string>(type: "nvarchar(max)", nullable: true),
HaveDexterityBonus = table.Column<bool>(type: "bit", nullable: false),
MinimumStrength = table.Column<int>(type: "int", nullable: true),
HaveStealthDisadvantage = table.Column<bool>(type: "bit", nullable: false),
Weight = table.Column<int>(type: "int", nullable: false),
Cost = table.Column<int>(type: "int", nullable: false),
CurrencyType = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Armors", x => x.Id);
});
migrationBuilder.CreateTable(
name: "OtherEquipment",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
Description = table.Column<string>(type: "nvarchar(max)", nullable: true),
Cost = table.Column<int>(type: "int", nullable: false),
CurrencyType = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OtherEquipment", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Weapons",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
Cost = table.Column<int>(type: "int", nullable: false),
Weight = table.Column<int>(type: "int", nullable: false),
CurrencyType = table.Column<int>(type: "int", nullable: false),
DiceCount = table.Column<int>(type: "int", nullable: false),
DiceValue = table.Column<int>(type: "int", nullable: false),
TwoHandDiceCount = table.Column<int>(type: "int", nullable: true),
TwoHandDiceValue = table.Column<int>(type: "int", nullable: true),
TwoHandDamageType = table.Column<string>(type: "nvarchar(max)", nullable: true),
Description = table.Column<string>(type: "nvarchar(max)", nullable: true),
WeaponType = table.Column<string>(type: "nvarchar(max)", nullable: true),
RangeMeele = table.Column<int>(type: "int", nullable: false),
RangeThrowNormal = table.Column<int>(type: "int", nullable: true),
RangeThrowLong = table.Column<int>(type: "int", nullable: true),
RangeLong = table.Column<int>(type: "int", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Weapons", x => x.Id);
});
migrationBuilder.CreateTable(
name: "CharacterArmors",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CharacterId = table.Column<int>(type: "int", nullable: false),
ArmorId = table.Column<int>(type: "int", nullable: false),
InUse = table.Column<bool>(type: "bit", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CharacterArmors", x => x.Id);
table.ForeignKey(
name: "FK_CharacterArmors_Armors_ArmorId",
column: x => x.ArmorId,
principalTable: "Armors",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_CharacterArmors_Characters_CharacterId",
column: x => x.CharacterId,
principalTable: "Characters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "CharacterOtherEquipment",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CharacterId = table.Column<int>(type: "int", nullable: false),
OtherEquipmentId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CharacterOtherEquipment", x => x.Id);
table.ForeignKey(
name: "FK_CharacterOtherEquipment_Characters_CharacterId",
column: x => x.CharacterId,
principalTable: "Characters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_CharacterOtherEquipment_OtherEquipment_OtherEquipmentId",
column: x => x.OtherEquipmentId,
principalTable: "OtherEquipment",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "CharacterWeapons",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CharacterId = table.Column<int>(type: "int", nullable: false),
WeaponId = table.Column<int>(type: "int", nullable: false),
InUse = table.Column<bool>(type: "bit", nullable: false),
HoldInRightHand = table.Column<bool>(type: "bit", nullable: false),
HoldInLeftHand = table.Column<bool>(type: "bit", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CharacterWeapons", x => x.Id);
table.ForeignKey(
name: "FK_CharacterWeapons_Characters_CharacterId",
column: x => x.CharacterId,
principalTable: "Characters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_CharacterWeapons_Weapons_WeaponId",
column: x => x.WeaponId,
principalTable: "Weapons",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Armors",
columns: new[] { "Id", "ArmorClassBase", "Category", "Cost", "CurrencyType", "HaveDexterityBonus", "HaveStealthDisadvantage", "MinimumStrength", "Name", "Weight" },
values: new object[,]
{
{ 1, "11", "Light", 5, 3, true, true, 0, "Padded", 8 },
{ 13, "2", "Shield", 10, 3, false, false, 0, "Shield", 6 },
{ 12, "18", "Heavy", 1500, 3, false, true, 15, "Plate", 65 },
{ 11, "17", "Heavy", 200, 3, false, true, 15, "Splint", 60 },
{ 9, "14", "Heavy", 30, 3, false, true, 0, "Ring Mail", 40 },
{ 8, "15", "Medium", 750, 3, true, true, 0, "Half Plate", 40 },
{ 10, "16", "Heavy", 75, 3, false, true, 13, "Chain Mail", 55 },
{ 6, "14", "Medium", 50, 3, true, true, 0, "Scale Mail", 45 },
{ 5, "13", "Medium", 50, 3, true, false, 0, "Chain Shirt", 20 },
{ 4, "12", "Medium", 10, 3, true, false, 0, "Hide", 12 },
{ 3, "12", "Light", 45, 3, true, false, 0, "Studded Leather", 13 },
{ 2, "11", "Light", 10, 3, true, false, 0, "Leather", 10 },
{ 7, "14", "Medium", 400, 3, true, false, 0, "Breastplate", 20 }
});
migrationBuilder.InsertData(
table: "OtherEquipment",
columns: new[] { "Id", "Cost", "CurrencyType", "Description", "Name" },
values: new object[,]
{
{ 92, 5, 0, "", "Signal whistle" },
{ 88, 1, 0, "", "Sack" },
{ 89, 5, 3, " A scale includes a small balance, pans, and a suitable assortment of weights up to 2 pounds. With it, you can measure the exact weight of small objects, such as raw precious metals or trade goods, to help determine their worth.", "Scale, merchant's" },
{ 90, 5, 1, "", "Sealing wax" },
{ 91, 2, 3, "", "Shovel" },
{ 93, 5, 3, "", "Signet ring" },
{ 100, 1, 0, " A torch burns for 1 hour, providing bright light in a 20-foot radius and dim light for an additional 20 feet. If you make a melee attack with a burning torch and hit, it deals 1 fire damage.", "Torch" },
{ 95, 50, 3, " Essential for wizards, a spellbook is a leather-bound tome with 100 blank vellum pages suitable for recording spells.", "Spellbook" },
{ 96, 1, 1, "", "Spike, iron" },
{ 97, 1000, 3, " Objects viewed through a spyglass are magnified to twice their size.", "Spyglass" },
{ 98, 2, 3, " A simple and portable canvas shelter, a tent sleeps two.", "Tent, two-person" },
{ 99, 5, 1, " This small container holds flint, fire steel, and tinder (usually dry cloth soaked in light oil) used to kindle a fire. Using it to light a torch--or anything else with abundant, exposed fuel--takes an action. Lighting any other fire takes 1 minute.", "Tinderbox" },
{ 87, 10, 3, " Rope, whether made of hemp or silk, has 2 hit points and can be burst with a DC 17 Strength check.", "Rope, silk (50 feet)" },
{ 94, 2, 0, "", "Soap" },
{ 86, 1, 3, " Rope, whether made of hemp or silk, has 2 hit points and can be burst with a DC 17 Strength check.", "Rope, hempen (50 feet)" },
{ 79, 50, 3, " A character who drinks the magical red fluid in this vial regains 2d4 + 2 hit points. Drinking or administering a potion takes an action.", "Potion of healing" },
{ 84, 5, 3, " A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Appendix B lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.", "Reliquary" },
{ 83, 5, 1, " Rations consist of dry foods suitable for extended travel, including jerky, dried fruit, hardtack, and nuts.", "Rations (1 day)" },
{ 82, 4, 3, " You can use a portable ram to break down doors. When doing so, you gain a +4 bonus on the Strength check. One other character can help you use the ram, giving you advantage on this check.", "Ram, portable" },
{ 81, 1, 3, " A quiver can hold up to 20 arrows.", "Quiver" },
{ 101, 1, 3, "", "Vial" },
{ 78, 2, 3, "", "Pot, iron" },
{ 77, 5, 0, "", "Pole (10-foot)" },
{ 76, 100, 3, " You can use the poison in this vial to coat one slashing or piercing weapon or up to three pieces of ammunition. Applying the poison takes an action. A creature hit by the poisoned weapon or ammunition must make a DC 10 Constitution saving throw or take 1d4 poison damage. Once applied, the poison retains potency for 1 minute before drying.", "Poison, basic (vial)" },
{ 75, 5, 0, "", "Piton" },
{ 74, 2, 3, "", "Pick, miner's" },
{ 73, 5, 3, "", "Perfume (vial)" },
{ 72, 1, 1, "", "Parchment (one sheet)" },
{ 71, 2, 1, "", "Paper (one sheet)" }
});
migrationBuilder.InsertData(
table: "OtherEquipment",
columns: new[] { "Id", "Cost", "CurrencyType", "Description", "Name" },
values: new object[,]
{
{ 70, 1, 1, " Oil usually comes in a clay flask that holds 1 pint. As an action, you can splash the oil in this flask onto a creature within 5 feet of you or throw it up to 20 feet, shattering it on impact. Make a ranged attack against a target creature or object, treating the oil as an improvised weapon. On a hit, the target is covered in oil. If the target takes any fire damage before the oil dries (after 1 minute), the target takes an additional 5 fire damage from the burning oil. You can also pour a flask of oil on the ground to cover a 5-foot-square area, provided that the surface is level. If lit, the oil burns for 2 rounds and deals 5 fire damage to any creature that enters the area or ends its turn in the area. A creature can take this damage only once per turn.", "Oil (flask)" },
{ 85, 1, 3, "", "Robes" },
{ 102, 2, 1, "", "Waterskin" },
{ 109, 15, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Cartographer's tools" },
{ 104, 16, 3, "", "Burglar's Pack" },
{ 135, 25, 3, " This set of tools includes a small file, a set of lock picks, a small mirror mounted on a metal handle, a set of narrow-bladed scissors, and a pair of pliers. Proficiency with these tools lets you add your proficiency bonus to any ability checks you make to disarm traps or open locks.", "Thieves' tools" },
{ 134, 25, 3, " This set of instruments is used for navigation at sea. Proficiency with navigator's tools lets you chart a ship's course and follow navigation charts. In addition, these tools allow you to add your proficiency bonus to any ability check you make to avoid getting lost at sea.", "Navigator's tools" },
{ 133, 30, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Viol" },
{ 132, 2, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Shawm" },
{ 131, 12, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Pan flute" },
{ 130, 3, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Horn" },
{ 129, 30, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Lyre" },
{ 128, 35, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Lute" },
{ 127, 2, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Flute" },
{ 126, 25, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Dulcimer" },
{ 125, 6, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Drum" },
{ 124, 30, 3, " Several of the most common types of musical instruments are shown on the table as examples. If you have proficiency with a given musical instrument, you can add your proficiency bonus to any ability checks you make to play music with the instrument. A bard can use a musical instrument as a spellcasting focus. Each type of musical instrument requires a separate proficiency.", "Bagpipes" },
{ 123, 5, 1, " This item encompasses a wide range of game pieces, including dice and decks of cards (for games such as Three-Dragon Ante). A few common examples appear on the Tools table, but other kinds of gaming sets exist. If you are proficient with a gaming set, you can add your proficiency bonus to ability checks you make to play a game with that set. Each type of gaming set requires a separate proficiency.", "Playing card set" },
{ 122, 1, 1, " This item encompasses a wide range of game pieces, including dice and decks of cards (for games such as Three-Dragon Ante). A few common examples appear on the Tools table, but other kinds of gaming sets exist. If you are proficient with a gaming set, you can add your proficiency bonus to ability checks you make to play a game with that set. Each type of gaming set requires a separate proficiency.", "Dice set" },
{ 121, 1, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Woodcarver's tools" },
{ 120, 1, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Weaver's tools" },
{ 119, 50, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Tinker's tools" },
{ 105, 50, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Alchemist's supplies" },
{ 106, 20, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Brewer's supplies" },
{ 107, 10, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Calligrapher's supplies" },
{ 108, 8, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Carpenter's tools" },
{ 69, 5, 3, "", "Mirror, steel" },
{ 110, 5, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Cobbler's tools" },
{ 103, 1, 0, "", "Whetstone" },
{ 111, 1, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Cook's utensils" },
{ 113, 25, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Jeweler's tools" },
{ 114, 5, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Leatherworker's tools" },
{ 115, 10, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Mason's tools" },
{ 116, 10, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Painter's supplies" },
{ 117, 10, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Potter's tools" },
{ 118, 20, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Smith's tools" },
{ 112, 30, 3, " These special tools include the items needed to pursue a craft or trade. The table shows examples of the most common types of tools, each providing items related to a single craft. Proficiency with a set of artisan's tools lets you add your proficiency bonus to any ability checks you make using the tools in your craft. Each type of artisan's tools requires a separate proficiency.", "Glassblower's tools" },
{ 68, 2, 3, " These metal restraints can bind a Small or Medium creature. Escaping the manacles requires a successful DC 20 Dexterity check. Breaking them requires a successful DC 20 Strength check. Each set of manacles comes with one key. Without the key, a creature proficient with thieves' tools can pick the manacles' lock with a successful DC 15 Dexterity check. Manacles have 15 hit points.", "Manacles" },
{ 80, 5, 1, " A cloth or leather pouch can hold up to 20 sling bullets or 50 blowgun needles, among other things. A compartmentalized pouch for holding spell components is called a component pouch (described earlier in this section).", "Pouch" },
{ 66, 10, 3, " A key is provided with the lock. Without the key, a creature proficient with thieves' tools can pick this lock with a successful DC 15 Dexterity check. Your GM may decide that better locks are available for higher prices.", "Lock" },
{ 31, 1, 0, "", "Chalk (1 piece)" },
{ 30, 5, 3, " A chain has 10 hit points. It can be burst with a successful DC 20 Strength check.", "Chain (10 feet)" }
});
migrationBuilder.InsertData(
table: "OtherEquipment",
columns: new[] { "Id", "Cost", "CurrencyType", "Description", "Name" },
values: new object[,]
{
{ 29, 1, 3, " This cylindrical leather case can hold up to ten rolled-up sheets of paper or five rolled-up sheets of parchment.", "Case, map or scroll" },
{ 28, 1, 3, " This wooden case can hold up to twenty crossbow bolts.", "Case, crossbow bolt" },
{ 27, 1, 0, " For 1 hour, a candle sheds bright light in a 5-foot radius and dim light for an additional 5 feet.", "Candle" },
{ 26, 5, 0, " As an action, you can spread a bag of caltrops to cover a square area that is 5 feet on a side. Any creature that enters the area must succeed on a DC 15 Dexterity saving throw or stop moving this turn and take 1 piercing damage. Taking this damage reduces the creature's walking speed by 10 feet until the creature regains at least 1 hit point. A creature moving through the area at half speed doesn't need to make the save.", "Caltrops" },
{ 25, 5, 0, "", "Bucket" },
{ 24, 2, 3, "", "Bottle, glass" },
{ 23, 25, 3, " A book might contain poetry, historical accounts, information pertaining to a particular field of lore, diagrams and notes on gnomish contraptions, or just about anything else that can be represented using text or pictures. A book of spells is a spellbook (described later in this section).", "Book" },
{ 22, 1, 3, " A set of pulleys with a cable threaded through them and a hook to attach to objects, a block and tackle allows you to hoist up to four times the weight you can normally lift.", "Block and tackle" },
{ 21, 5, 1, "", "Blanket" },
{ 20, 1, 3, "", "Bell" },
{ 19, 1, 3, "", "Bedroll" },
{ 18, 4, 1, "", "Basket" },
{ 17, 2, 3, "", "Barrel" },
{ 67, 100, 3, " This lens allows a closer look at small objects. It is also useful as a substitute for flint and steel when starting fires. Lighting a fire with a magnifying glass requires light as bright as sunlight to focus, tinder to ignite, and about 5 minutes for the fire to ignite. A magnifying glass grants advantage on any ability check made to appraise or inspect an item that is small or highly detailed.", "Magnifying glass" },
{ 15, 2, 3, "", "Backpack" },
{ 1, 2, 3, "", "Abacus" },
{ 2, 25, 3, " As an action, you can splash the contents of this vial onto a creature within 5 feet of you or throw the vial up to 20 feet, shattering it on impact. In either case, make a ranged attack against a creature or object, treating the acid as an improvised weapon. On a hit, the target takes 2d6 acid damage.", "Acid (vial)" },
{ 3, 50, 3, " This sticky, adhesive fluid ignites when exposed to air. As an action, you can throw this flask up to 20 feet, shattering it on impact. Make a ranged attack against a creature or object, treating the alchemist's fire as an improvised weapon. On a hit, the target takes 1d4 fire damage at the start of each of its turns. A creature can end this damage by using its action to make a DC 10 Dexterity check to extinguish the flames.", "Alchemist's fire (flask)" },
{ 4, 5, 0, "", "Arrow" },
{ 5, 2, 0, "", "Blowgun needle" },
{ 6, 5, 0, "", "Crossbow bolt" },
{ 32, 5, 3, "", "Chest" },
{ 7, 1, 0, "", "Sling bullet" },
{ 9, 50, 3, " A creature that drinks this vial of liquid gains advantage on saving throws against poison for 1 hour. It confers no benefit to undead or constructs.", "Antitoxin (vial)" },
{ 10, 10, 3, " An arcane focus is a special item--an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item--designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.", "Crystal" },
{ 11, 20, 3, " An arcane focus is a special item--an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item--designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.", "Orb" },
{ 12, 10, 3, " An arcane focus is a special item--an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item--designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.", "Rod" },
{ 13, 5, 3, " An arcane focus is a special item--an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item--designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.", "Staff" },
{ 14, 10, 3, " An arcane focus is a special item--an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item--designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.", "Wand" },
{ 8, 5, 3, " A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Appendix B lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.", "Amulet" },
{ 33, 5, 1, "", "Clothes, common" },
{ 16, 1, 3, " As an action, you can spill these tiny metal balls from their pouch to cover a level, square area that is 10 feet on a side. A creature moving across the covered area must succeed on a DC 10 Dexterity saving throw or fall prone. A creature moving through the area at half speed doesn't need to make the save.", "Ball bearings (bag of 1,000)" },
{ 35, 15, 3, "", "Clothes, fine" },
{ 34, 5, 3, "", "Clothes, costume" },
{ 65, 5, 3, " A hooded lantern casts bright light in a 30-foot radius and dim light for an additional 30 feet. Once lit, it burns for 6 hours on a flask (1 pint) of oil. As an action, you can lower the hood, reducing the light to dim light in a 5-foot radius.", "Lantern, hooded" },
{ 64, 10, 3, " A bullseye lantern casts bright light in a 60-foot cone and dim light for an additional 60 feet. Once lit, it burns for 6 hours on a flask (1 pint) of oil.", "Lantern, bullseye" },
{ 63, 5, 1, " A lamp casts bright light in a 15-foot radius and dim light for an additional 30 feet. Once lit, it burns for 6 hours on a flask (1 pint) of oil.", "Lamp" },
{ 62, 1, 1, "", "Ladder (10-foot)" },
{ 61, 50, 3, " A poisoner's kit includes the vials, chemicals, and other equipment necessary for the creation of poisons. Proficiency with this kit lets you add your proficiency bonus to any ability checks you make to craft or use poisons.", "Poisoner's Kit" },
{ 60, 2, 1, " This tin box contains a cup and simple cutlery. The box clamps together, and one side can be used as a cooking pan and the other as a plate or shallow bowl.", "Mess Kit" },
{ 59, 5, 3, " This kit is a leather pouch containing bandages, salves, and splints. The kit has ten uses. As an action, you can expend one use of the kit to stabilize a creature that has 0 hit points, without needing to make a Wisdom (Medicine) check.", "Healer's Kit" },
{ 57, 15, 3, " This small box contains a variety of papers and parchments, pens and inks, seals and sealing wax, gold and silver leaf, and other supplies necessary to create convincing forgeries of physical documents. Proficiency with this kit lets you add your proficiency bonus to any ability checks you make to create a physical forgery of a document.", "Forgery Kit" }
});
migrationBuilder.InsertData(
table: "OtherEquipment",
columns: new[] { "Id", "Cost", "CurrencyType", "Description", "Name" },
values: new object[,]
{
{ 56, 25, 3, " This pouch of cosmetics, hair dye, and small props lets you create disguises that change your physical appearance. Proficiency with this kit lets you add your proficiency bonus to any ability checks you make to create a visual disguise.", "Disguise Kit" },
{ 55, 25, 3, " A climber's kit includes special pitons, boot tips, gloves, and a harness. You can use the climber's kit as an action to anchor yourself; when you do, you can't fall more than 25 feet from the point where you anchored yourself, and you can't climb more than 25 feet away from that point without undoing the anchor.", "Climber's Kit" },
{ 54, 2, 0, "", "Jug or pitcher" },
{ 53, 2, 0, "", "Ink pen" },
{ 52, 10, 3, "", "Ink (1 ounce bottle)" },
{ 51, 5, 3, " When you use your action to set it, this trap forms a saw-toothed steel ring that snaps shut when a creature steps on a pressure plate in the center. The trap is affixed by a heavy chain to an immobile object, such as a tree or a spike driven into the ground. A creature that steps on the plate must succeed on a DC 13 Dexterity saving throw or take 1d4 piercing damage and stop moving. Thereafter, until the creature breaks free of the trap, its movement is limited by the length of the chain (typically 3 feet long). A creature can use its action to make a DC 13 Strength check, freeing itself or another creature within its reach on a success. Each failed check deals 1 piercing damage to the trapped creature.", "Hunting trap" },
{ 58, 5, 3, " This kit contains a variety of instruments such as clippers, mortar and pestle, and pouches and vials used by herbalists to create remedies and potions. Proficiency with this kit lets you add your proficiency bonus to any ability checks you make to identify or apply herbs. Also, proficiency with this kit is required to create antitoxin and potions of healing.", "Herbalism Kit" },
{ 49, 25, 3, " As an action, you can splash the contents of this flask onto a creature within 5 feet of you or throw it up to 20 feet, shattering it on impact. In either case, make a ranged attack against a target creature, treating the holy water as an improvised weapon. If the target is a fiend or undead, it takes 2d6 radiant damage. A cleric or paladin may create holy water by performing a special ritual. The ritual takes 1 hour to perform, uses 25 gp worth of powdered silver, and requires the caster to expend a 1st-level spell slot.", "Holy water (flask)" },
{ 36, 2, 3, "", "Clothes, traveler's" },
{ 50, 25, 3, "", "Hourglass" },
{ 37, 25, 3, " A component pouch is a small, watertight leather belt pouch that has compartments to hold all the material components and other special items you need to cast your spells, except for those components that have a specific cost (as indicated in a spell's description).", "Component pouch" },
{ 38, 2, 3, " Using a crowbar grants advantage to Strength checks where the crowbar's leverage can be applied.", "Crowbar" },
{ 39, 1, 3, " A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.", "Sprig of mistletoe" },
{ 40, 1, 3, " A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.", "Totem" },
{ 42, 10, 3, " A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.", "Yew wand" },
{ 41, 5, 3, " A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.", "Wooden staff" },
{ 44, 1, 3, " This kit includes a wooden rod, silken line, corkwood bobbers, steel hooks, lead sinkers, velvet lures, and narrow netting.", "Fishing tackle" },
{ 45, 2, 0, "", "Flask or tankard" },
{ 46, 2, 3, "", "Grappling hook" },
{ 47, 1, 3, "", "Hammer" },
{ 48, 2, 3, "", "Hammer, sledge" },
{ 43, 5, 3, " A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Appendix B lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.", "Emblem" }
});
migrationBuilder.InsertData(
table: "Weapons",
columns: new[] { "Id", "Cost", "CurrencyType", "Description", "DiceCount", "DiceValue", "Name", "RangeLong", "RangeMeele", "RangeThrowLong", "RangeThrowNormal", "TwoHandDamageType", "TwoHandDiceCount", "TwoHandDiceValue", "WeaponType", "Weight" },
values: new object[,]
{
{ 22, 15, 3, null, 1, 8, "Longsword", null, 5, null, null, null, 1, 10, "Martial Melee", 3 },
{ 26, 25, 3, null, 1, 8, "Rapier", null, 5, null, null, null, null, null, "Martial Melee", 2 },
{ 21, 10, 3, "You have disadvantage when you use a lance to attack a target within 5 feet of you. Also, a lance requires two hands to wield when you aren<65>t mounted.", 1, 12, "Lance", null, 5, null, null, null, null, null, "Martial Melee", 6 },
{ 23, 10, 3, null, 2, 6, "Maul", null, 5, null, null, null, null, null, "Martial Melee", 10 },
{ 24, 15, 3, null, 1, 8, "Morningstar", null, 5, null, null, null, null, null, "Martial Melee", 4 },
{ 25, 5, 3, null, 1, 10, "Pike", null, 5, null, null, null, null, null, "Martial Melee", 18 },
{ 27, 25, 3, null, 1, 6, "Scimitar", null, 5, null, null, null, null, null, "Martial Melee", 3 },
{ 34, 75, 3, null, 1, 6, "Crossbow, hand", null, 5, null, null, null, null, null, "Martial Ranged", 3 },
{ 29, 5, 3, null, 1, 6, "Trident", null, 5, 60, 20, null, null, null, "Martial Melee", 4 },
{ 30, 5, 3, null, 1, 8, "War pick", null, 5, null, null, null, null, null, "Martial Melee", 2 },
{ 31, 15, 3, null, 1, 8, "Warhammer", null, 5, null, null, null, 1, 10, "Martial Melee", 2 },
{ 32, 2, 3, null, 1, 4, "Whip", null, 5, null, null, null, null, null, "Martial Melee", 3 },
{ 33, 10, 3, null, 1, 1, "Blowgun", null, 5, null, null, null, null, null, "Martial Ranged", 1 },
{ 20, 20, 3, null, 1, 10, "Halberd", null, 5, null, null, null, null, null, "Martial Melee", 6 },
{ 35, 50, 3, null, 1, 10, "Crossbow, heavy", null, 5, null, null, null, null, null, "Martial Ranged", 18 },
{ 28, 10, 3, null, 1, 6, "Shortsword", null, 5, null, null, null, null, null, "Martial Melee", 2 },
{ 19, 50, 3, null, 2, 6, "Greatsword", null, 5, null, null, null, null, null, "Martial Melee", 6 },
{ 3, 2, 1, null, 1, 8, "Greatclub", null, 5, null, null, null, null, null, "Simple Melee", 10 },
{ 17, 20, 3, null, 1, 10, "Glaive", null, 5, null, null, null, null, null, "Martial Melee", 6 },
{ 36, 50, 3, null, 1, 8, "Longbow", null, 5, null, null, null, null, null, "Martial Ranged", 2 }
});
migrationBuilder.InsertData(
table: "Weapons",
columns: new[] { "Id", "Cost", "CurrencyType", "Description", "DiceCount", "DiceValue", "Name", "RangeLong", "RangeMeele", "RangeThrowLong", "RangeThrowNormal", "TwoHandDamageType", "TwoHandDiceCount", "TwoHandDiceValue", "WeaponType", "Weight" },
values: new object[,]
{
{ 1, 1, 1, null, 1, 4, "Club", null, 5, null, null, null, null, null, "Simple Melee", 2 },
{ 2, 2, 3, null, 1, 4, "Dagger", null, 5, 60, 20, null, null, null, "Simple Melee", 1 },
{ 4, 5, 3, null, 1, 6, "Handaxe", null, 5, 60, 20, null, null, null, "Simple Melee", 2 },
{ 5, 5, 1, null, 1, 6, "Javelin", null, 5, 120, 30, null, null, null, "Simple Melee", 2 },
{ 6, 2, 3, null, 1, 4, "Light hammer", null, 5, 60, 20, null, null, null, "Simple Melee", 2 },
{ 7, 5, 3, null, 1, 6, "Mace", null, 5, null, null, null, null, null, "Simple Melee", 4 },
{ 18, 30, 3, null, 1, 12, "Greataxe", null, 5, null, null, null, null, null, "Martial Melee", 7 },
{ 8, 2, 1, null, 1, 6, "Quarterstaff", null, 5, null, null, null, 1, 8, "Simple Melee", 4 },
{ 10, 1, 3, null, 1, 4, "Spear", null, 5, 60, 20, null, 1, 8, "Simple Melee", 3 },
{ 11, 25, 3, null, 1, 8, "Crossbow, light", null, 5, null, null, null, null, null, "Simple Ranged", 5 },
{ 12, 5, 0, null, 1, 4, "Dart", null, 5, 60, 20, null, null, null, "Simple Ranged", 0 },
{ 13, 25, 3, null, 1, 6, "Shortbow", null, 5, null, null, null, null, null, "Simple Ranged", 2 },
{ 14, 1, 1, null, 1, 4, "Sling", null, 5, null, null, null, null, null, "Simple Ranged", 0 },
{ 15, 10, 3, null, 1, 8, "Battleaxe", null, 5, null, null, null, 1, 10, "Martial Melee", 4 },
{ 16, 10, 3, null, 1, 8, "Flail", null, 5, null, null, null, null, null, "Martial Melee", 2 },
{ 9, 1, 3, null, 1, 4, "Sickle", null, 5, null, null, null, null, null, "Simple Melee", 2 },
{ 37, 1, 3, "A Large or smaller creature hit by a net is restrained until it is freed. A net has no effect on creatures that are formless, or creatures that are Huge or larger. A creature can use its action to make a DC 10 Strength check, freeing itself or another creature within its reach on a success. Dealing 5 slashing damage to the net (AC 10) also frees the creature without harming it, ending the effect and destroying the net. When you use an action, bonus action, or reaction to attack with a net, you can make only one attack regardless of the number of attacks you can normally make.", 1, 0, "Net", null, 5, 15, 5, null, null, null, "Martial Ranged", 3 }
});
migrationBuilder.InsertData(
table: "CharacterArmors",
columns: new[] { "Id", "ArmorId", "CharacterId", "InUse" },
values: new object[,]
{
{ 1, 1, 1, true },
{ 3, 2, 2, true },
{ 6, 2, 3, false },
{ 2, 3, 1, false },
{ 4, 5, 2, false },
{ 5, 6, 3, true }
});
migrationBuilder.InsertData(
table: "CharacterOtherEquipment",
columns: new[] { "Id", "CharacterId", "OtherEquipmentId" },
values: new object[,]
{
{ 5, 3, 6 },
{ 4, 2, 5 },
{ 2, 1, 3 },
{ 6, 3, 2 },
{ 3, 2, 2 },
{ 1, 1, 1 }
});
migrationBuilder.InsertData(
table: "CharacterWeapons",
columns: new[] { "Id", "CharacterId", "HoldInLeftHand", "HoldInRightHand", "InUse", "WeaponId" },
values: new object[,]
{
{ 1, 1, false, false, false, 1 },
{ 3, 2, false, true, true, 2 },
{ 2, 1, true, false, true, 4 },
{ 7, 3, false, true, true, 7 },
{ 4, 2, false, false, false, 8 },
{ 5, 3, false, false, false, 9 }
});
migrationBuilder.CreateIndex(
name: "IX_CharacterArmors_ArmorId",
table: "CharacterArmors",
column: "ArmorId");
migrationBuilder.CreateIndex(
name: "IX_CharacterArmors_CharacterId",
table: "CharacterArmors",
column: "CharacterId");
migrationBuilder.CreateIndex(
name: "IX_CharacterOtherEquipment_CharacterId",
table: "CharacterOtherEquipment",
column: "CharacterId");
migrationBuilder.CreateIndex(
name: "IX_CharacterOtherEquipment_OtherEquipmentId",
table: "CharacterOtherEquipment",
column: "OtherEquipmentId");
migrationBuilder.CreateIndex(
name: "IX_CharacterWeapons_CharacterId",
table: "CharacterWeapons",
column: "CharacterId");
migrationBuilder.CreateIndex(
name: "IX_CharacterWeapons_WeaponId",
table: "CharacterWeapons",
column: "WeaponId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "CharacterArmors");
migrationBuilder.DropTable(
name: "CharacterOtherEquipment");
migrationBuilder.DropTable(
name: "CharacterWeapons");
migrationBuilder.DropTable(
name: "Armors");
migrationBuilder.DropTable(
name: "OtherEquipment");
migrationBuilder.DropTable(
name: "Weapons");
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Database.Repositories
{
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
public class ArmorRepository : Repository<Armor>, IRepository<Armor>
{
public ArmorRepository(ApplicationDbContext _dbContext) : base(_dbContext)
{ }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Database.Repositories
{
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
public class CharacterArmorRepository : Repository<CharacterArmor>, IRepository<CharacterArmor>
{
public CharacterArmorRepository(ApplicationDbContext _dbContext) : base(_dbContext)
{ }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Database.Repositories
{
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
public class CharacterOtherEquipmentRepository : Repository<CharacterOtherEquipment>, IRepository<CharacterOtherEquipment>
{
public CharacterOtherEquipmentRepository(ApplicationDbContext _dbContext) : base(_dbContext)
{ }
}
}

View File

@ -0,0 +1,14 @@
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Database.Repositories
{
public class CharacterWeaponRepository: Repository<CharacterWeapon>, IRepository<CharacterWeapon>
{
public CharacterWeaponRepository(ApplicationDbContext _dbContext) : base(_dbContext)
{ }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Database.Repositories
{
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
public class OtherEquipmentRepository : Repository<OtherEquipment>, IRepository<OtherEquipment>
{
public OtherEquipmentRepository(ApplicationDbContext _dbContext) : base(_dbContext)
{ }
}
}

View File

@ -0,0 +1,14 @@
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Database.Repositories
{
public class WeaponRepository : Repository<Weapon>, IRepository<Weapon>
{
public WeaponRepository(ApplicationDbContext _dbContext) : base(_dbContext)
{ }
}
}

View File

@ -66,17 +66,17 @@ namespace SessionCompanion.Database
new Class
{
Id = 1,
Name = "Warrior"
Name = "Fighter"
},
new Class
{
Id = 2,
Name = "Knight"
Name = "Paladin"
},
new Class
{
Id = 3,
Name = "Priest"
Name = "Cleric"
}
};
return classes;
@ -232,5 +232,161 @@ namespace SessionCompanion.Database
};
return characters;
}
static public List<CharacterWeapon> SeedCharacterWeapon()
{
List<CharacterWeapon> characterWeapons = new List<CharacterWeapon>
{
new CharacterWeapon
{
Id = 1,
CharacterId = 1,
WeaponId = 1,
InUse = false,
HoldInLeftHand = false,
HoldInRightHand = false
},
new CharacterWeapon
{
Id = 2,
CharacterId = 1,
WeaponId = 4,
InUse = true,
HoldInLeftHand = true,
HoldInRightHand = false
},
new CharacterWeapon
{
Id = 3,
CharacterId = 2,
WeaponId = 2,
InUse = true,
HoldInLeftHand = false,
HoldInRightHand = true
},
new CharacterWeapon
{
Id = 4,
CharacterId = 2,
WeaponId = 8,
InUse = false,
HoldInLeftHand = false,
HoldInRightHand = false
},
new CharacterWeapon
{
Id = 5,
CharacterId = 3,
WeaponId = 9,
InUse = false,
HoldInLeftHand = false,
HoldInRightHand = false
},
new CharacterWeapon
{
Id = 7,
CharacterId = 3,
WeaponId = 7,
InUse = true,
HoldInLeftHand = false,
HoldInRightHand = true
}
};
return characterWeapons;
}
static public List<CharacterArmor> SeedCharacterArmor()
{
List<CharacterArmor> characterArmors = new List<CharacterArmor>
{
new CharacterArmor
{
Id = 1,
CharacterId = 1,
ArmorId = 1,
InUse = true,
},
new CharacterArmor
{
Id = 2,
CharacterId = 1,
ArmorId = 3,
InUse = false,
},
new CharacterArmor
{
Id = 3,
CharacterId = 2,
ArmorId = 2,
InUse = true,
},
new CharacterArmor
{
Id = 4,
CharacterId = 2,
ArmorId = 5,
InUse = false,
},
new CharacterArmor
{
Id = 5,
CharacterId = 3,
ArmorId = 6,
InUse = true,
},
new CharacterArmor
{
Id = 6,
CharacterId = 3,
ArmorId = 2,
InUse = false,
}
};
return characterArmors;
}
static public List<CharacterOtherEquipment> SeedCharacterOtherEquipment()
{
List<CharacterOtherEquipment> characterOtherEquipment = new List<CharacterOtherEquipment>
{
new CharacterOtherEquipment
{
Id = 1,
CharacterId = 1,
OtherEquipmentId = 1
},
new CharacterOtherEquipment
{
Id = 2,
CharacterId = 1,
OtherEquipmentId = 3
},
new CharacterOtherEquipment
{
Id = 3,
CharacterId = 2,
OtherEquipmentId = 2
},
new CharacterOtherEquipment
{
Id = 4,
CharacterId = 2,
OtherEquipmentId = 5
},
new CharacterOtherEquipment
{
Id = 5,
CharacterId = 3,
OtherEquipmentId = 6
},
new CharacterOtherEquipment
{
Id = 6,
CharacterId = 3,
OtherEquipmentId = 2
}
};
return characterOtherEquipment;
}
}
}

View File

@ -0,0 +1,124 @@
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SessionCompanion.Database
{
public static class SeedFromJsons
{
static public Weapon SingleWeaponSeeder(dynamic item)
{
Weapon weapon = new Weapon();
// Id
weapon.Id = item.index;
// Name
weapon.Name = item.name;
// Weapon type
weapon.WeaponType = item.category_range;
// Cost
weapon.Cost = item.cost.quantity;
// CurrnecyType
switch ((string)item.cost.unit)
{
case "sp":
weapon.CurrencyType = CurrencyType.sp;
break;
case "gp":
weapon.CurrencyType = CurrencyType.gp;
break;
}
// DiceCount
weapon.DiceCount = item.damage.dice_count;
// DiceValue
weapon.DiceValue = item.damage.dice_value;
// RangeMeele
weapon.RangeMeele = item.range.normal;
// RangeLong
weapon.RangeLong = item.range._long;
// RangeThrow
if (item.throw_range != null)
{
weapon.RangeThrowNormal = item.throw_range.normal;
weapon.RangeThrowLong = item.throw_range._long;
}
// Weight
weapon.Weight = item.weight;
// Twohand
if (item.two_hand_damage != null)
{
weapon.TwoHandDiceCount = item.two_hand_damage.dice_count;
weapon.TwoHandDiceValue = item.two_hand_damage.dice_value;
}
if (item.special != null)
weapon.Description = item.special[0];
return weapon;
}
static public Armor SingleArmorSeeder(dynamic item, int id)
{
Armor armor = new Armor();
armor.Id = id;
armor.Name = item.name;
armor.Category = item.armor_category;
armor.ArmorClassBase = item.armor_class["base"];
armor.HaveDexterityBonus = item.armor_class["dex_bonus"];
armor.MinimumStrength = item.str_minimum;
armor.HaveStealthDisadvantage = item.stealth_disadvantage;
armor.Weight = item.weight;
armor.Cost = item.cost.quantity;
switch ((string)item.cost.unit)
{
case "sp":
armor.CurrencyType = CurrencyType.sp;
break;
case "gp":
armor.CurrencyType = CurrencyType.gp;
break;
}
return armor;
}
static public OtherEquipment SingleOtherEquipmentSeeder(dynamic item, int id)
{
OtherEquipment otherEq = new OtherEquipment();
otherEq.Id = id;
otherEq.Name = item.name;
if (item.desc != null)
foreach (dynamic description in item.desc)
otherEq.Description += " " + description;
else
otherEq.Description = string.Empty;
otherEq.Cost = item.cost.quantity;
switch ((string)item.cost.unit)
{
case "sp":
otherEq.CurrencyType = CurrencyType.sp;
break;
case "gp":
otherEq.CurrencyType = CurrencyType.gp;
break;
}
return otherEq;
}
}
}

View File

@ -21,4 +21,8 @@
<ProjectReference Include="..\SessionCompanion.ViewModels\SessionCompanion.ViewModels.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="JsonData\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,21 @@
using SessionCompanion.ViewModels.Enums;
using System.Collections.Generic;
namespace SessionCompanion.Database.Tables
{
public class Armor : BaseEntity
{
public string Name { get; set; }
public string Category { get; set; }
public string ArmorClassBase {get; set; }
public bool HaveDexterityBonus { get; set; }
public int? MinimumStrength { get; set; }
public bool HaveStealthDisadvantage { get; set; }
public int Weight { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
public virtual ICollection<CharacterArmor> CharacterArmors { get; set; }
}
}

View File

@ -0,0 +1,18 @@
namespace SessionCompanion.Database.Tables
{
using System.ComponentModel.DataAnnotations.Schema;
public class CharacterArmor : BaseEntity
{
[ForeignKey(nameof(Character))]
public int CharacterId { get; set; }
public virtual Character Character { get; set; }
[ForeignKey(nameof(Armor))]
public int ArmorId { get; set; }
public virtual Armor Armor { get; set; }
public bool InUse { get; set; }
}
}

View File

@ -0,0 +1,15 @@
namespace SessionCompanion.Database.Tables
{
using System.ComponentModel.DataAnnotations.Schema;
public class CharacterOtherEquipment : BaseEntity
{
[ForeignKey(nameof(Character))]
public int CharacterId { get; set; }
public virtual Character Character { get; set; }
[ForeignKey(nameof(OtherEquipment))]
public int OtherEquipmentId { get; set; }
public virtual OtherEquipment OtherEquipment { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace SessionCompanion.Database.Tables
{
public class CharacterWeapon : BaseEntity
{
[ForeignKey(nameof(Character))]
public int CharacterId { get; set; }
public virtual Character Character { get; set; }
[ForeignKey(nameof(Weapon))]
public int WeaponId { get; set; }
public virtual Weapon Weapon { get; set; }
public bool InUse { get; set; }
public bool HoldInRightHand { get; set; }
public bool HoldInLeftHand { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using SessionCompanion.ViewModels.Enums;
using System.Collections.Generic;
namespace SessionCompanion.Database.Tables
{
public class OtherEquipment : BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
public virtual ICollection<CharacterOtherEquipment> CharacterOtherEquipments { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using SessionCompanion.ViewModels.Enums;
using System.Collections.Generic;
namespace SessionCompanion.Database.Tables
{
public class Weapon : BaseEntity
{
public string Name { get; set; }
public int Cost { get; set; }
public int Weight { get; set; }
public CurrencyType CurrencyType { get; set; }
public int DiceCount { get; set; }
public int DiceValue { get; set; }
public int? TwoHandDiceCount { get; set; }
public int? TwoHandDiceValue { get; set; }
public string TwoHandDamageType { get; set; }
public string Description { get; set; }
public string WeaponType { get; set; }
public int RangeMeele { get; set; }
public int? RangeThrowNormal { get; set; }
public int? RangeThrowLong { get; set; }
public int? RangeLong { get; set; }
public virtual ICollection<CharacterWeapon> CharacterWeapons { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Interfaces
{
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.ViewModels.ArmorViewModels;
public interface IArmorService : IServiceBase<ArmorViewModel, Armor>
{
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Interfaces
{
using System.Threading.Tasks;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.ViewModels.CharacterArmorViewModels;
public interface ICharacterArmorService : IServiceBase<CharacterArmorViewModel, CharacterArmor>
{
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Interfaces
{
using System.Threading.Tasks;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.ViewModels.CharacterOtherEquipmentViewModels;
public interface ICharacterOtherEquipmentService : IServiceBase<CharacterOtherEquipmentViewModel, CharacterOtherEquipment>
{
}
}

View File

@ -0,0 +1,10 @@
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.ViewModels.CharacterWeaponViewModels;
namespace SessionCompanion.Services.Interfaces
{
public interface ICharacterWeaponService : IServiceBase<CharacterWeaponViewModel, CharacterWeapon>
{
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Interfaces
{
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.ViewModels.OtherEquipmentViewModels;
public interface IOtherEquipmentService : IServiceBase<OtherEquipmentViewModel, OtherEquipment>
{
}
}

View File

@ -0,0 +1,13 @@
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.ViewModels.WeaponViewModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Interfaces
{
public interface IWeaponService : IServiceBase<WeaponViewModel, Weapon>
{
}
}

View File

@ -0,0 +1,14 @@
using AutoMapper;
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.ArmorViewModels;
namespace SessionCompanion.Services.Profiles
{
public class ArmorProfile : Profile
{
public ArmorProfile()
{
CreateMap<Armor, ArmorViewModel>().ReverseMap();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Profiles
{
using AutoMapper;
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.CharacterArmorViewModels;
public class CharacterArmorsProfile : Profile
{
public CharacterArmorsProfile()
{
CreateMap<CharacterArmorViewModel, CharacterArmor>().ReverseMap();
CreateMap<CharacterArmor, CharacterArmorViewModelDetails>()
.ForMember(vm => vm.Name, conf => conf.MapFrom(armor => armor.Armor.Name.ToString()))
.ForMember(vm => vm.Category, conf => conf.MapFrom(armor => armor.Armor.Category.ToString()))
.ForMember(
vm => vm.ArmorClassBase,
conf => conf.MapFrom(armor => armor.Armor.ArmorClassBase.ToString()))
.ForMember(vm => vm.HaveDexterityBonus, conf => conf.MapFrom(armor => armor.Armor.HaveDexterityBonus))
.ForMember(vm => vm.MinimumStrength, conf => conf.MapFrom(armor => armor.Armor.MinimumStrength))
.ForMember(
vm => vm.HaveStealthDisadvantage,
conf => conf.MapFrom(armor => armor.Armor.HaveStealthDisadvantage))
.ForMember(vm => vm.Weight, conf => conf.MapFrom(armor => armor.Armor.Weight))
.ForMember(vm => vm.Cost, conf => conf.MapFrom(armor => armor.Armor.Cost))
.ForMember(vm => vm.CurrencyType, conf => conf.MapFrom(armor => armor.Armor.CurrencyType)).ReverseMap();
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Profiles
{
using AutoMapper;
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.CharacterOtherEquipmentViewModels;
public class CharacterOtherEquipmentsProfile : Profile
{
public CharacterOtherEquipmentsProfile()
{
CreateMap<CharacterOtherEquipmentViewModel, CharacterOtherEquipment>().ReverseMap();
CreateMap<CharacterOtherEquipment, CharacterOtherEquipmentWithDetailsViewModel>()
.ForMember(vm => vm.Name, conf => conf.MapFrom(otherEquipment => otherEquipment.OtherEquipment.Name.ToString()))
.ForMember(
vm => vm.Description,
conf => conf.MapFrom(otherEquipment => otherEquipment.OtherEquipment.Description.ToString()))
.ForMember(
vm => vm.Cost,
conf => conf.MapFrom(otherEquipment => otherEquipment.OtherEquipment.Cost))
.ForMember(
vm => vm.CurrencyType,
conf => conf.MapFrom(otherEquipment => otherEquipment.OtherEquipment.CurrencyType)).ReverseMap();
}
}
}

View File

@ -23,7 +23,8 @@ namespace SessionCompanion.Services.Profiles
CreateMap<Character, CharacterBasicStatsViewModel>()
.ForMember(vm => vm.Name, conf => conf.MapFrom(charact => charact.Biography.Name))
.ForMember(vm => vm.Level, conf => conf.MapFrom(charact => charact.Statistics.Level))
.ForMember(vm => vm.CurrentHealthPoints, conf => conf.MapFrom(charact => charact.Statistics.CurrentHealthPoints)).ReverseMap();
.ForMember(vm => vm.CurrentHealthPoints, conf => conf.MapFrom(charact => charact.Statistics.CurrentHealthPoints))
.ForMember(vm => vm.Class, conf => conf.MapFrom(charact => charact.Biography.Class.Name)).ReverseMap();
}
}
}

View File

@ -0,0 +1,32 @@
using AutoMapper;
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.CharacterWeaponViewModels;
namespace SessionCompanion.Services.Profiles
{
public class CharacterWeaponsProfile : Profile
{
public CharacterWeaponsProfile()
{
CreateMap<CharacterWeaponViewModel, CharacterWeapon>().ReverseMap();
CreateMap<CharacterWeapon, CharacterWeaponWithWeaponDetailsViewModel>()
.ForMember(vm => vm.Name, conf => conf.MapFrom(weapon => weapon.Weapon.Name.ToString()))
.ForMember(vm => vm.Weight, conf => conf.MapFrom(weapon => weapon.Weapon.Weight.ToString()))
.ForMember(vm => vm.HoldInRightHand, conf => conf.MapFrom(weapon => weapon.HoldInRightHand))
.ForMember(vm => vm.HoldInLeftHand, conf => conf.MapFrom(weapon => weapon.HoldInLeftHand))
.ForMember(vm => vm.Cost, conf => conf.MapFrom(weapon => weapon.Weapon.Cost.ToString()))
.ForMember(vm => vm.RangeMeele, conf => conf.MapFrom(weapon => weapon.Weapon.RangeMeele))
.ForMember(vm => vm.RangeLong, conf => conf.MapFrom(weapon => weapon.Weapon.RangeLong))
.ForMember(vm => vm.RangeThrowNormal, conf => conf.MapFrom(weapon => weapon.Weapon.RangeThrowNormal))
.ForMember(vm => vm.RangeThrowLong, conf => conf.MapFrom(weapon => weapon.Weapon.RangeThrowLong))
.ForMember(vm => vm.CurrencyType, conf => conf.MapFrom(weapon => weapon.Weapon.CurrencyType.ToString()))
.ForMember(vm => vm.WeaponType, conf => conf.MapFrom(weapon => weapon.Weapon.WeaponType.ToString()))
.ForMember(vm => vm.Description, conf => conf.MapFrom(weapon => weapon.Weapon.Description))
.ForMember(vm => vm.DiceValue, conf => conf.MapFrom(weapon => weapon.Weapon.DiceValue))
.ForMember(vm => vm.DiceCount, conf => conf.MapFrom(weapon => weapon.Weapon.DiceCount))
.ForMember(vm => vm.TwoHandDiceValue, conf => conf.MapFrom(weapon => weapon.Weapon.TwoHandDiceValue))
.ForMember(vm => vm.TwoHandDamageType, conf => conf.MapFrom(weapon => weapon.Weapon.TwoHandDamageType.ToString())).ReverseMap();
}
}
}

View File

@ -0,0 +1,14 @@
using AutoMapper;
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.OtherEquipmentViewModels;
namespace SessionCompanion.Services.Profiles
{
public class OtherEquipmentProfile : Profile
{
public OtherEquipmentProfile()
{
CreateMap<OtherEquipmentViewModel, OtherEquipment>().ReverseMap();
}
}
}

View File

@ -0,0 +1,14 @@
using AutoMapper;
using SessionCompanion.Database.Tables;
using SessionCompanion.ViewModels.WeaponViewModels;
namespace SessionCompanion.Services.Profiles
{
public class WeaponProfile : Profile
{
public WeaponProfile()
{
CreateMap<WeaponViewModel, Weapon>().ReverseMap();
}
}
}

View File

@ -0,0 +1,16 @@
namespace SessionCompanion.Services.Services
{
using AutoMapper;
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.Services.Interfaces;
using SessionCompanion.ViewModels.ArmorViewModels;
public class ArmorService : ServiceBase<ArmorViewModel, Armor>, IArmorService
{
public ArmorService(IMapper mapper, IRepository<Armor> repository) : base(mapper, repository)
{ }
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Services
{
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.Services.Interfaces;
using SessionCompanion.ViewModels.CharacterArmorViewModels;
public class CharacterArmorService : ServiceBase<CharacterArmorViewModel, CharacterArmor>, ICharacterArmorService
{
public CharacterArmorService(IMapper mapper, IRepository<CharacterArmor> repository) : base(mapper, repository)
{ }
}
}

View File

@ -0,0 +1,17 @@
namespace SessionCompanion.Services.Services
{
using AutoMapper;
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.Services.Interfaces;
using SessionCompanion.ViewModels.CharacterOtherEquipmentViewModels;
public class CharacterOtherEquipmentService : ServiceBase<CharacterOtherEquipmentViewModel, CharacterOtherEquipment>, ICharacterOtherEquipmentService
{
public CharacterOtherEquipmentService(IMapper mapper, IRepository<CharacterOtherEquipment> repository) : base(mapper, repository)
{ }
}
}

View File

@ -46,6 +46,7 @@ namespace SessionCompanion.Services.Services
{
var characters = await Repository.Get(c => charactersId.Contains(c.Id))
.Include(x => x.Biography)
.ThenInclude(x => x.Class)
.Include(x => x.Statistics).ToListAsync();
var result = Mapper.Map<IEnumerable<CharacterBasicStatsViewModel>>(characters);
return result;

View File

@ -0,0 +1,15 @@
using AutoMapper;
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.Services.Interfaces;
using SessionCompanion.ViewModels.CharacterWeaponViewModels;
namespace SessionCompanion.Services.Services
{
public class CharacterWeaponService : ServiceBase<CharacterWeaponViewModel, CharacterWeapon>, ICharacterWeaponService
{
public CharacterWeaponService(IMapper mapper, IRepository<CharacterWeapon> repository) : base(mapper, repository)
{ }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Services
{
using AutoMapper;
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.Services.Interfaces;
using SessionCompanion.ViewModels.OtherEquipmentViewModels;
public class OtherEquipmentService : ServiceBase<OtherEquipmentViewModel, OtherEquipment>, IOtherEquipmentService
{
public OtherEquipmentService(IMapper mapper, IRepository<OtherEquipment> repository) : base(mapper, repository)
{ }
}
}

View File

@ -0,0 +1,18 @@
using AutoMapper;
using SessionCompanion.Database.Repositories.Base;
using SessionCompanion.Database.Tables;
using SessionCompanion.Services.Base;
using SessionCompanion.Services.Interfaces;
using SessionCompanion.ViewModels.WeaponViewModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.Services.Services
{
public class WeaponService : ServiceBase<WeaponViewModel, Weapon>, IWeaponService
{
public WeaponService(IMapper mapper, IRepository<Weapon> repository) : base(mapper, repository)
{ }
}
}

View File

@ -0,0 +1,18 @@
namespace SessionCompanion.ViewModels.ArmorViewModels
{
using SessionCompanion.ViewModels.Enums;
public class ArmorViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public string ArmorClassBase { get; set; }
public bool HaveDexterityBonus { get; set; }
public int? MinimumStrength { get; set; }
public bool HaveStealthDisadvantage { get; set; }
public int Weight { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.ViewModels.CharacterArmorViewModels
{
public class CharacterArmorViewModel
{
public int Id { get; set; }
public int CharacterId { get; set; }
public int ArmorId { get; set; }
public bool InUse { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using SessionCompanion.ViewModels.Enums;
namespace SessionCompanion.ViewModels.CharacterArmorViewModels
{
public class CharacterArmorViewModelDetails
{
public int Id { get; set; }
public int CharacterId { get; set; }
public int ArmorId { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public string ArmorClassBase { get; set; }
public bool HaveDexterityBonus { get; set; }
public int? MinimumStrength { get; set; }
public bool HaveStealthDisadvantage { get; set; }
public int Weight { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
public bool InUse { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SessionCompanion.ViewModels.CharacterOtherEquipmentViewModels
{
public class CharacterOtherEquipmentViewModel
{
public int Id { get; set; }
public int CharacterId { get; set; }
public int OtherEquipmentId { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using SessionCompanion.ViewModels.Enums;
namespace SessionCompanion.ViewModels.CharacterOtherEquipmentViewModels
{
public class CharacterOtherEquipmentWithDetailsViewModel
{
public int Id { get; set; }
public int CharacterId { get; set; }
public int OtherEquipmentId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
}
}

View File

@ -21,5 +21,10 @@
/// Aktualna ilość życia postaci
/// </summary>
public int CurrentHealthPoints { get; set; }
/// <summary>
/// Klasa postaci
/// </summary>
public string Class { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace SessionCompanion.ViewModels.CharacterWeaponViewModels
{
public class CharacterWeaponViewModel
{
public int Id { get; set; }
public int CharacterId { get; set; }
public int WeaponId { get; set; }
public bool InUse { get; set; }
public bool HoldInRightHand { get; set; }
public bool HoldInLeftHand { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using SessionCompanion.ViewModels.Enums;
using System.Collections.Generic;
namespace SessionCompanion.ViewModels.CharacterWeaponViewModels
{
public class CharacterWeaponWithWeaponDetailsViewModel
{
public int WeaponId { get; set; }
public bool InUse { get; set; }
public string Name { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
public int Weight { get; set; }
public bool HoldInRightHand { get; set; }
public bool HoldInLeftHand { get; set; }
public int DiceCount { get; set; }
public int DiceValue { get; set; }
public int? TwoHandDiceCount { get; set; }
public int? TwoHandDiceValue { get; set; }
public string TwoHandDamageType { get; set; }
public string Description { get; set; }
public string WeaponType { get; set; }
public int RangeMeele { get; set; }
public int? RangeThrowNormal { get; set; }
public int? RangeThrowLong { get; set; }
public int? RangeLong { get; set; }
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SessionCompanion.ViewModels.Enums
{
/// <summary>
/// Rodzaje waluty
/// </summary>
public enum CurrencyType
{
/// <summary>
/// Bronz
/// </summary>
cp,
/// <summary>
/// Srebro
/// </summary>
sp,
/// <summary>
/// Elektrum
/// </summary>
ep,
/// <summary>
/// Złoto
/// </summary>
gp,
/// <summary>
/// Platyna
/// </summary>
pp
}
}

View File

@ -0,0 +1,13 @@
namespace SessionCompanion.ViewModels.OtherEquipmentViewModels
{
using SessionCompanion.ViewModels.Enums;
public class OtherEquipmentViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Cost { get; set; }
public CurrencyType CurrencyType { get; set; }
}
}

View File

@ -100,6 +100,11 @@
Aktualna ilość życia postaci
</summary>
</member>
<member name="P:SessionCompanion.ViewModels.CharacterViewModels.CharacterBasicStatsViewModel.Class">
<summary>
Klasa postaci
</summary>
</member>
<member name="P:SessionCompanion.ViewModels.CharacterViewModels.CharacterForLoginViewModel.Id">
<summary>
Identyfikator postaci
@ -305,6 +310,36 @@
Czy postać posiada biegłość w skradaniu się
</summary>
</member>
<member name="T:SessionCompanion.ViewModels.Enums.CurrencyType">
<summary>
Rodzaje waluty
</summary>
</member>
<member name="F:SessionCompanion.ViewModels.Enums.CurrencyType.cp">
<summary>
Bronz
</summary>
</member>
<member name="F:SessionCompanion.ViewModels.Enums.CurrencyType.sp">
<summary>
Srebro
</summary>
</member>
<member name="F:SessionCompanion.ViewModels.Enums.CurrencyType.ep">
<summary>
Elektrum
</summary>
</member>
<member name="F:SessionCompanion.ViewModels.Enums.CurrencyType.gp">
<summary>
Złoto
</summary>
</member>
<member name="F:SessionCompanion.ViewModels.Enums.CurrencyType.pp">
<summary>
Platyna
</summary>
</member>
<member name="P:SessionCompanion.ViewModels.IntelligenceViewModels.IntelligenceViewModel.Id">
<summary>
Identyfikator inteligencji postaci

View File

@ -0,0 +1,29 @@
using SessionCompanion.ViewModels.Enums;
using System.Collections.Generic;
namespace SessionCompanion.ViewModels.WeaponViewModels
{
public class WeaponViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Cost { get; set; }
public int Weight { get; set; }
public CurrencyType CurrencyType { get; set; }
public int DiceCount { get; set; }
public int DiceValue { get; set; }
public int? TwoHandDiceCount { get; set; }
public int? TwoHandDiceValue { get; set; }
public string TwoHandDamageType { get; set; }
public string Description { get; set; }
public string WeaponType { get; set; }
public int RangeMeele { get; set; }
public int? RangeThrowNormal { get; set; }
public int? RangeThrowLong { get; set; }
public int? RangeLong { get; set; }
}
}

View File

@ -0,0 +1,3 @@
{
"singleQuote": true
}

View File

@ -9747,6 +9747,12 @@
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
"dev": true
},
"prettier": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
"integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
"dev": true
},
"private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
@ -12040,6 +12046,12 @@
}
}
},
"tslint-config-prettier": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz",
"integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==",
"dev": true
},
"tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",

View File

@ -53,6 +53,7 @@
"karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"prettier": "2.2.1",
"typescript": "3.5.3"
},
"optionalDependencies": {

View File

@ -1,9 +1,17 @@
import { Component } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {SessionCompanionIconsRegistry} from './shared/sc-icons/session-companion-icons-registry.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
export class AppComponent implements OnInit{
title = 'Session Companion';
constructor(private iconService: SessionCompanionIconsRegistry) {
}
ngOnInit() {
this.iconService.registerIcons();
}
}

View File

@ -23,9 +23,10 @@ import {
import {UserService} from '../services/user.service';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { reducers} from './reducers';
import {AppReducer} from './store/reducers/app.reducer';
import {environment} from '../environments/environment';
import {reducers} from './store/models/app-state.model';
import {CharacterService} from '../services/character.service';
import { AbilityCardComponent } from './components/ability-card/ability-card.component';
@NgModule({
declarations: [
@ -36,6 +37,7 @@ import {environment} from '../environments/environment';
GameMasterDashboardComponent,
PlayerDashboardComponent,
SelectCharacterComponent,
AbilityCardComponent,
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
@ -54,13 +56,14 @@ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
MatSidenavModule,
MatToolbarModule,
MatListModule,
StoreModule.forRoot({appState: AppReducer}),
StoreModule.forRoot(reducers),
StoreDevtoolsModule.instrument({
logOnly: environment.production
})
],
providers: [
UserService
UserService,
CharacterService
],
bootstrap: [AppComponent]
})

View File

@ -0,0 +1,31 @@
#main{
width: 480px;
height: 480px;
}
#main>.mat-card{
padding: 0;
}
.diagonal-line{
width:50px;
background:linear-gradient(45deg,rgb(16 32 40 / 0%) 49%,black,#ffffff00 51%);
}
#ability-card-content{
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding-top: 10px;
padding-bottom: 10px;
}
#skill-btn{
border-color: black;
flex: 1 0 auto;
margin-bottom: 10px;
margin-left: 10px;
margin-right: 10px;
}
#skill-btn-divider{
border-left: black 1px solid;
padding-right: 10px;
padding-top: 10px;
padding-bottom: 10px;
}

View File

@ -0,0 +1,24 @@
<div *ngIf="ability" id="main">
<mat-card>
<mat-card-header id="ability-card-header" [style.background]="headStyle.bgColor" [style.color]="headStyle.textColor">
{{ability.value}}
<div class="diagonal-line"></div>
Mod: {{ability.modification > 0? '+' + ability.modification : '-' + ability.modification}}
<div class="diagonal-line"></div>
{{ability.name}}
<div *ngIf="ability.canSaveThrows" class="diagonal-line" style="margin-left: auto"></div>
<div *ngIf="ability.canSaveThrows" style="margin-right: 10px">
ST: {{ability.savingThrows > 0? '+' + ability.savingThrows : '-' + ability.savingThrows}}
</div>
</mat-card-header>
<mat-divider [style.border-top-color]="'black'"></mat-divider>
<mat-card-content id="ability-card-content" [style.background]="contentStyle.bgColor" [style.color]="contentStyle.textColor">
<a mat-stroked-button *ngFor="let skill of ability.skills" id="skill-btn">
{{skill.name}}
&nbsp; &nbsp;
<span id="skill-btn-divider"></span>
{{skill.value > 0? '+' + skill.value : '-' + skill.value}}
</a>
</mat-card-content>
</mat-card>
</div>

View File

@ -0,0 +1,19 @@
import { Component, Input, OnInit } from '@angular/core';
import { AbilityViewModel } from '../../../types/viewmodels/ability-viewmodels/AbilityViewModel';
@Component({
selector: 'app-ability-card',
templateUrl: './ability-card.component.html',
styleUrls: ['./ability-card.component.css'],
})
export class AbilityCardComponent implements OnInit {
@Input() ability: AbilityViewModel;
@Input() headStyle: { bgColor: string; textColor: string };
@Input() contentStyle: { bgColor: string; textColor: string };
constructor() {}
ngOnInit() {
this.ability.skills.sort((a, b) => (a.name > b.name ? 1 : -1));
}
}

View File

@ -1,56 +1,96 @@
<div class="root-container" >
<mat-sidenav-container class="sidenav-container">
<mat-sidenav class="leftnav" opened mode="side" [@onSideNavChange]="leftSidenavExpanded ? 'open' : 'close'">
<div style="background-color: #292F36">
<button mat-icon-button (click)="UpdateSidenavStatus('left', !leftSidenavTextExpanded)" style="margin: 12px; ">
<mat-icon aria-label="Menu">menu</mat-icon>
</button>
</div>
<mat-divider></mat-divider>
<mat-nav-list>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<span [@animateText]="leftSidenavTextExpanded ? 'show' : 'hide'" style="color: white">Link 1</span>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<span [@animateText]="leftSidenavTextExpanded ? 'show' : 'hide'" style="color: white">Link 2</span>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<span [@animateText]="leftSidenavTextExpanded ? 'show' : 'hide'" style="color: white">Link 3</span>
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content >
<mat-toolbar color="primary" class="gm-toolbar">
<span>SessionCompanion</span>
</mat-toolbar>
</mat-sidenav-content>
<mat-sidenav class="rightnav" opened mode="side" position="end" [@onSideNavChange]="rightSidenavExpanded ? 'open' : 'close'">
<div style="background-color: #4F5B69">
<button mat-icon-button (click)="UpdateSidenavStatus('right', !rightSidenavExpanded)" style="margin: 12px; ">
<mat-icon aria-label="Menu">chat</mat-icon>
</button>
<button mat-icon-button *ngIf="rightSidenavTextExpanded" (click)="UpdateSidenavStatus('right', !rightSidenavExpanded)" style="margin: 12px; position: absolute; right: 10px;">
<mat-icon aria-label="Menu">close</mat-icon>
</button>
</div>
<mat-divider></mat-divider>
<mat-nav-list>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<a [@animateText]="rightSidenavTextExpanded ? 'show' : 'hide'" mat-list-item href="#" style="color: white">Link 1</a>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<a [@animateText]="rightSidenavTextExpanded ? 'show' : 'hide'" mat-list-item href="#" style="color: white">Link 2</a>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<a [@animateText]="rightSidenavTextExpanded ? 'show' : 'hide'" mat-list-item href="#" style="color: white">Link 3</a>
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
</mat-sidenav-container>
<div class="root-container">
<mat-sidenav-container class="sidenav-container">
<mat-sidenav
class="leftnav"
opened
mode="side"
[@onSideNavChange]="leftSidenavExpanded ? 'open' : 'close'"
>
<div style="background-color: #292f36">
<button
mat-icon-button
(click)="UpdateSidenavStatus('left', !leftSidenavTextExpanded)"
style="margin: 12px"
>
<mat-icon aria-label="Menu">menu</mat-icon>
</button>
</div>
<mat-divider></mat-divider>
<mat-nav-list>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<span
[@animateText]="leftSidenavTextExpanded ? 'show' : 'hide'"
style="color: white"
>Link 1</span
>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<span
[@animateText]="leftSidenavTextExpanded ? 'show' : 'hide'"
style="color: white"
>Link 2</span
>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder</mat-icon>
<span
[@animateText]="leftSidenavTextExpanded ? 'show' : 'hide'"
style="color: white"
>Link 3</span
>
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<mat-toolbar color="primary" class="gm-toolbar">
<span>SessionCompanion</span>
</mat-toolbar>
</mat-sidenav-content>
<mat-sidenav
class="rightnav"
opened
mode="side"
position="end"
[@onSideNavChange]="rightSidenavExpanded ? 'open' : 'close'"
>
<div style="background-color: #4f5b69">
<button
mat-icon-button
(click)="UpdateSidenavStatus('right', !rightSidenavExpanded)"
style="margin: 12px"
>
<mat-icon aria-label="Menu">chat</mat-icon>
</button>
<button
mat-icon-button
*ngIf="rightSidenavTextExpanded"
(click)="UpdateSidenavStatus('right', !rightSidenavExpanded)"
style="margin: 12px; position: absolute; right: 10px"
>
<mat-icon aria-label="Menu">close</mat-icon>
</button>
</div>
<mat-divider></mat-divider>
<mat-nav-list>
<mat-list-item *ngFor="let loggedCharacter of loggedCharacters">
<mat-icon
svgIcon="{{ loggedCharacter.class.toLowerCase() }}"
mat-list-icon
style="font-size: 0"
></mat-icon>
<span
[@animateText]="rightSidenavTextExpanded ? 'show' : 'hide'"
style="color: white"
>{{
loggedCharacter.name.length > 12
? (loggedCharacter.name | slice: 0:12) + '..'
: loggedCharacter.name
}}</span
>
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
</mat-sidenav-container>
</div>

View File

@ -1,20 +1,37 @@
import {Component, OnInit} from '@angular/core';
import {animateText, onSideNavChange} from '../../shared/animations/sidenav-animations';
import {GMSignalRService} from '../../shared/signalR-service/gm-signalR.service';
import { Component, OnDestroy, OnInit } from '@angular/core';
import {
animateText,
onSideNavChange,
} from '../../shared/animations/sidenav-animations';
import { GMSignalRService } from '../../shared/signalR-service/gm-signalR.service';
import { CharacterService } from '../../../services/character.service';
import { Subscription } from 'rxjs';
import { ErrorResponse } from '../../../types/ErrorResponse';
import { HttpErrorResponse } from '@angular/common/http';
import { LoggedCharactersViewModel } from '../../../types/viewmodels/character-viewmodels/LoggedCharactersViewModel';
import { first } from 'rxjs/operators';
@Component({
selector: 'app-game-master-dashboard',
templateUrl: './game-master-dashboard.component.html',
styleUrls: ['./game-master-dashboard.component.css'],
animations: [onSideNavChange, animateText]
animations: [onSideNavChange, animateText],
})
export class GameMasterDashboardComponent implements OnInit {
export class GameMasterDashboardComponent implements OnInit, OnDestroy {
allSubscriptions = new Subscription();
leftSidenavExpanded = false;
leftSidenavTextExpanded = false;
rightSidenavExpanded = false;
rightSidenavTextExpanded = false;
constructor(private signalRService: GMSignalRService) {}
loggedCharacters: LoggedCharactersViewModel[];
constructor(
private signalRService: GMSignalRService,
private characterService: CharacterService
) {
this.SubscribeToEvents();
}
ngOnInit() {
this.signalRService.Login();
@ -36,4 +53,36 @@ export class GameMasterDashboardComponent implements OnInit {
break;
}
}
UpdateCharactersList(): void {
this.characterService
.getLoggedCharacters()
.pipe(first())
.subscribe(
(success) => {
this.loggedCharacters = success;
},
(error: ErrorResponse | HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
error = error.error as ErrorResponse;
}
console.error(error.message);
}
);
}
private SubscribeToEvents(): void {
this.signalRService.message.subscribe((message: string) => {
if (
message === 'New player connected' ||
message === 'Player disconnected'
) {
this.UpdateCharactersList();
}
});
}
ngOnDestroy() {
this.allSubscriptions.unsubscribe();
}
}

View File

@ -0,0 +1,44 @@
@import "../../../styles.css";
.menu-spacer {
flex: 1 1 auto;
}
.root-container {
height: calc(100vh - 64px);
}
@media (max-width: 768px) {
.root-container {
height: calc(100vh - 58px);
}
}
.sidenav-container {
flex: 1;
height: 100%;
}
.content {
background-color: #102028;
color: #df7c0f;
}
.navbar {
background-color: #df7c0f;
color: #e9cca7;
}
.sidenav {
background-color: #102028;
}
.mat-list-item.active{
color: #e9cca7;
}
.ability_card_container {
margin: 5%;
display: flex;
justify-content: center;
align-items: center;
}

View File

@ -0,0 +1,59 @@
<div class="root-container">
<mat-toolbar>
<mat-toolbar-row class="navbar">
<button mat-icon-button (click)="sidenav.toggle()" fxShow="true" fxHide.gt-sm>
<mat-icon>menu</mat-icon>
</button>
<span class="menu-spacer"></span>
<div fxShow="true" fxHide.lt-md>
<span>Session Companion</span>
</div>
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container class="sidenav-container">
<mat-sidenav #sidenav class="sidenav">
<mat-nav-list>
<mat-list-item [routerLink]="['/player']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>home</mat-icon>
<a matLine>Home</a>
</mat-list-item>
<mat-list-item [routerLink]="['/player/statistic']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>query_stats</mat-icon>
<a matLine>Statistic and throws</a>
</mat-list-item>
<mat-list-item [routerLink]="['/player/equipment']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>local_mall</mat-icon>
<a matLine>Equipment</a>
</mat-list-item>
<mat-list-item [routerLink]="['/player/spells']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>brightness_4</mat-icon>
<a matLine>Spells</a>
</mat-list-item>
<mat-list-item [routerLink]="['/player/profile']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>account_circle</mat-icon>
<a matLine>Profile</a>
</mat-list-item>
<mat-list-item [routerLink]="['/player/shop']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>shopping_cart</mat-icon>
<a matLine>Shop</a>
</mat-list-item>
<mat-list-item [routerLink]="['/']" [routerLinkActive]="['active']">
<mat-icon [class.active]="selected" matListIcon>exit_to_app</mat-icon>
<a matLine>Log out</a>
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content class="content">
<app-ability-card class="ability_card_container" [ability]="ability" [contentStyle]="{bgColor: 'red', textColor: 'white'}" [headStyle]="{bgColor: 'red', textColor: 'white'}"></app-ability-card>
</mat-sidenav-content>
</mat-sidenav-container>
</div>

View File

@ -1,12 +1,30 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import {AbilityViewModel} from "../../../types/viewmodels/ability-viewmodels/AbilityViewModel";
@Component({
selector: 'app-player-dashboard',
templateUrl: './player-dashboard.component.html',
styleUrls: ['./player-dashboard.component.css']
styleUrls: ['./player-dashboard.component.css'],
})
export class PlayerDashboardComponent {
isExpanded = false;
selected = false;
ability: AbilityViewModel = {
id: 1,
name: 'Strength',
value: 18,
modification: 2,
canSaveThrows: true,
savingThrows: 1,
skills: [
{
name: 'Throw',
value: 1,
can: false
}
]
}
collapse() {
this.isExpanded = false;

View File

@ -1,6 +1,6 @@
<div [formGroup]="signUpFormGroup" class="container">
<div formGroupName="newAccount" class="container">
<mat-icon matSuffix class="arrow-back" (click)="GoToLoginPage()">arrow_back</mat-icon>
<mat-icon matSuffix class="arrow-back arrow-select" (click)="GoToLoginPage()">arrow_back</mat-icon>
<div class="primary-text header">Create an Account</div>
<mat-form-field class="form-container">
@ -11,7 +11,7 @@
type="text"
required
name="username">
<mat-error *ngIf="signUpFormGroup?.get('newAccount')?.controls?.username?.hasError('required')">
<mat-error *ngIf="signUpFormGroup?.get('newAccount')['controls']?.username?.hasError('required')">
Username is required
</mat-error>
<mat-icon matSuffix>person</mat-icon>
@ -26,7 +26,7 @@
type="password"
name="password"/>
<mat-icon matSuffix>lock</mat-icon>
<mat-error *ngIf="signUpFormGroup?.get('newAccount')?.controls?.password?.hasError('required')">
<mat-error *ngIf="signUpFormGroup?.get('newAccount')['controls']?.password?.hasError('required')">
Password is required
</mat-error>
</mat-form-field>
@ -40,10 +40,10 @@
type="password"
name="confirmPassword"/>
<mat-icon matSuffix >lock</mat-icon>
<mat-error *ngIf="signUpFormGroup?.get('newAccount')?.controls?.confirmPassword?.hasError('required')">
<mat-error *ngIf="signUpFormGroup?.get('newAccount')['controls']?.confirmPassword?.hasError('required')">
Confirm your password
</mat-error>
<mat-error class="password-mismatch" *ngIf="signUpFormGroup?.get('newAccount')?.controls?.confirmPassword?.hasError('mismatch')">
<mat-error class="password-mismatch" *ngIf="signUpFormGroup?.get('newAccount')['controls']?.confirmPassword?.hasError('mismatch')">
Please make sure your passwords match
</mat-error>
</mat-form-field>

View File

@ -6,7 +6,6 @@ import {Subscription} from 'rxjs';
import {ErrorResponse} from '../../../types/ErrorResponse';
import {UserRegisterViewModel} from '../../../types/viewmodels/user-viewmodels/UserRegisterViewModel';
import {HttpErrorResponse} from '@angular/common/http';
import {type} from 'os';
@Component({
selector: 'app-registration',
@ -36,27 +35,33 @@ export class RegistrationComponent implements OnDestroy {
}
Register() {
const userRegisterModel = new class implements UserRegisterViewModel {
password: string;
username: string;
};
if (this.signUpFormGroup.valid) {
const userRegisterModel = new class implements UserRegisterViewModel {
password: string;
username: string;
};
userRegisterModel.username = this.signUpFormGroup.get('newAccount').value['username'];
userRegisterModel.password = this.signUpFormGroup.get('newAccount').value['password'];
userRegisterModel.username = this.signUpFormGroup.get('newAccount').value['username'];
userRegisterModel.password = this.signUpFormGroup.get('newAccount').value['password'];
this.allSubscriptions.add(
this.userService.registerUser(userRegisterModel).subscribe(
() => {
this.router.navigate(['login']);
},
(error: ErrorResponse | HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
error = error.error as ErrorResponse;
this.allSubscriptions.add(
this.userService.registerUser(userRegisterModel).subscribe(
() => {
this.router.navigate(['login']);
},
(error: ErrorResponse | HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
error = error.error as ErrorResponse;
}
this.apiError = true;
this.apiErrorMessage = error.message;
}
this.apiError = true;
this.apiErrorMessage = error.message;
}
));
));
} else {
this.signUpFormGroup.get('newAccount').get('username').markAsTouched();
this.signUpFormGroup.get('newAccount').get('password').markAsTouched();
this.signUpFormGroup.get('newAccount').get('confirmPassword').markAsTouched();
}
}
ngOnDestroy() {

View File

@ -47,10 +47,6 @@ input {
font-size: 20px;
}
.align-to-right {
text-align: right;
}
@media (max-width: 400px) {
.container {
margin-left: 0%;

View File

@ -1,21 +1,15 @@
<div class="container">
<mat-icon matSuffix class="arrow-back" (click)="onArrowBackClick()">arrow_back</mat-icon>
<mat-icon matSuffix class="arrow-back arrow-select" (click)="onArrowBackClick()">arrow_back</mat-icon>
<div class="primary-text header">Select character</div>
<mat-list >
<mat-list>
<mat-divider></mat-divider>
<mat-list-item> Oweja
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
<mat-list-item *ngFor="let character of charactersList">
<mat-icon mat-list-icon>account_circle</mat-icon>
<div mat-line>{{character.name}}</div>
<mat-icon matSuffix class="arrow-forward arrow-select" (click)="onCharacterClick(character.id)">arrow_forward</mat-icon>
<div mat-line> {{character.className}} level: {{character.level}}</div>
<mat-divider></mat-divider>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item> James
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item> Legolas
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</mat-list>
</div>

View File

@ -1,30 +1,49 @@
import { Component } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {first} from 'rxjs/operators';
import {ClearUserId} from '../../store/actions/app.actions';
import {ErrorResponse} from '../../../types/ErrorResponse';
import {HttpErrorResponse} from '@angular/common/http';
import {Store} from '@ngrx/store';
import {AppState} from '../../store/models/app-state.model';
import {CharacterService} from '../../../services/character.service';
import {CharacterForLoginViewModel} from '../../../types/viewmodels/character-viewmodels/CharacterForLoginViewModel';
import {AddCharacterId} from '../../store/actions/player.action';
@Component({
selector: 'app-select-character',
templateUrl: './select-character.component.html',
styleUrls: ['./select-character.component.css']
})
export class SelectCharacterComponent {
isExpanded = false;
export class SelectCharacterComponent implements OnInit {
charactersList: CharacterForLoginViewModel[];
collapse() {
this.isExpanded = false;
constructor(private router: Router, private store: Store<AppState>, private characterService: CharacterService) {}
ngOnInit() {
this.getUserCharactersList();
}
toggle() {
this.isExpanded = !this.isExpanded;
getUserCharactersList() {
this.store.select(s => s.appStore.userId).pipe(first()).subscribe((userId) => {
this.characterService.getUserCharactersList(userId).pipe(first()).subscribe((charactersList) => {
this.charactersList = charactersList;
}, (error: ErrorResponse | HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
error = error.error as ErrorResponse;
}
console.error(error.message);
} );
});
}
constructor(private router: Router) {}
onCharacterClick(){
this.router.navigate(['player'])
onCharacterClick(characterId: number) {
this.store.dispatch(new AddCharacterId({characterId}));
this.router.navigate(['player']);
}
onArrowBackClick(){
this.router.navigate(['login'])
onArrowBackClick() {
this.store.dispatch(new ClearUserId());
this.router.navigate(['login']);
}
}

View File

@ -12,7 +12,8 @@ import {AddRole} from '../../store/actions/app.actions';
export class SelectRoleComponent {
isExpanded = false;
constructor(private router: Router, private store: Store<{ role: string }>) {}
constructor(private router: Router, private store: Store<{ role: string }>) {
}
collapse() {
this.isExpanded = false;

View File

@ -1,6 +1,6 @@
<div [formGroup]="signInFormGroup" class="container">
<div formGroupName="signIn" class="container">
<mat-icon matSuffix class="arrow-back" (click)="onArrowBackClick()">arrow_back</mat-icon>
<mat-icon matSuffix class="arrow-back arrow-select" (click)="onArrowBackClick()">arrow_back</mat-icon>
<div id="SignInText" class="primary-text header">Sign In</div>
<mat-form-field class="form-container">
@ -12,7 +12,7 @@
type="text"
required
name="username">
<mat-error *ngIf="signInFormGroup?.get('signIn')?.controls?.username?.hasError('required')">
<mat-error *ngIf="signInFormGroup?.get('signIn')['controls']?.username?.hasError('required')">
Username is required
</mat-error>
<mat-icon matSuffix>person</mat-icon>
@ -28,7 +28,7 @@
type="password"
name="password"/>
<mat-icon matSuffix>lock</mat-icon>
<mat-error *ngIf="signInFormGroup?.get('signIn')?.controls?.password?.hasError('required')">
<mat-error *ngIf="signInFormGroup?.get('signIn')['controls']?.password?.hasError('required')">
Password is required
</mat-error>
</mat-form-field>

View File

@ -6,9 +6,10 @@ import {ErrorResponse} from '../../../types/ErrorResponse';
import {Observable, Subscription} from 'rxjs';
import {HttpErrorResponse} from '@angular/common/http';
import {AppStoreModel} from '../../store/models/app-store.model';
import { Store } from '@ngrx/store';
import {select, Store} from '@ngrx/store';
import {AddUserId} from '../../store/actions/app.actions';
import { AppState } from 'src/app/store/models/app-state.model';
import {AppState} from 'src/app/store/models/app-state.model';
import {first} from "rxjs/operators";
@Component({
selector: 'app-sign-in',
@ -38,12 +39,12 @@ export class SignInComponent implements OnDestroy, OnInit {
});
ngOnInit() {
this.role$ = this.store.select(s => s.appState);
this.role$ = this.store.select(s => s.appStore);
}
onLoginButtonClick() {
let role = '';
this.store.select(s => s.appState.role).subscribe((v)=>{
this.store.select(s => s.appStore.role).pipe(first()).subscribe((v) => {
role = v;
});
this.allSubscriptions.add(
@ -52,7 +53,6 @@ export class SignInComponent implements OnDestroy, OnInit {
this.signInFormGroup.get('signIn').value['password']).subscribe(
(success) => {
this.store.dispatch(new AddUserId({userId: success}));
//TODO zmienić na jedna linie
if (role === 'player') {
this.router.navigate(['select-character']);
} else {
@ -69,13 +69,12 @@ export class SignInComponent implements OnDestroy, OnInit {
));
}
onRegisterButtonClick(){
this.router.navigate(['register'])
//TODO connect with backend
onRegisterButtonClick() {
this.router.navigate(['register']);
}
onArrowBackClick(){
this.router.navigate([''])
onArrowBackClick() {
this.router.navigate(['']);
}
collapse() {

View File

@ -1,19 +0,0 @@
import {
ActionReducer,
ActionReducerMap,
createFeatureSelector,
createSelector,
MetaReducer
} from '@ngrx/store';
import { environment } from '../../environments/environment';
export interface State {
}
export const reducers: ActionReducerMap<State> = {
};
export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];

View File

@ -0,0 +1,4 @@
Moduł został już dodany i wstrzyknięty do roota apki.
Aby dodać nową ikonkę, plik svg wstawiamy do folderu assets/icons/svg-icons.
Oraz dodajym kolejnego enuma w pliku sc-icon.model.ts

View File

@ -0,0 +1,22 @@
import {Injectable} from '@angular/core';
import {scIcon} from '../../../assets/icons/sc-icon.model';
import {MatIconRegistry} from '@angular/material';
import {DomSanitizer} from '@angular/platform-browser';
@Injectable({
providedIn: 'root'
})
export class SessionCompanionIconsRegistry {
constructor(private registry: MatIconRegistry, private sanitizer: DomSanitizer) {
}
public registerIcons(): void {
this.loadIcons(Object.values(scIcon), '../assets/icons/svg-icons');
}
private loadIcons(iconKeys: string[], iconUrl: string): void {
iconKeys.forEach((icon: string) => {
this.registry.addSvgIcon(icon, this.sanitizer.bypassSecurityTrustResourceUrl(`${iconUrl}/${icon}.svg`));
});
}
}

View File

@ -1,12 +1,15 @@
import { Inject, Injectable } from '@angular/core';
import { SignalRService } from './base/signalR.service';
import {Subject} from 'rxjs';
@Injectable({ providedIn: 'root' })
export class GMSignalRService {
signalR: SignalRService;
message: Subject<string>;
constructor(@Inject('BASE_URL') baseUrl: string) {
this.signalR = new SignalRService(baseUrl);
this.message = new Subject<string>();
this.registerOnServerEvents();
}
@ -17,10 +20,15 @@ export class GMSignalRService {
if (this.signalR.connectionEstablished$.getValue() === true) {
this.signalR.hubConnection.send('GameMasterLogin');
}
});
}).unsubscribe();
}
private registerOnServerEvents(): void {
this.signalR.hubConnection.on('Welcome', (message: string) => {
this.message.next('New player connected');
});
this.signalR.hubConnection.on('GoodBye', (message: string) => {
this.message.next('Player disconnected');
});
}
}

View File

@ -1,9 +1,9 @@
import {AppStoreModel} from '../models/app-store.model';
import { Action } from '@ngrx/store';
import {Action} from '@ngrx/store';
export enum AppActionTypes {
ADD_USER_ID = '[APP] Add user id',
ADD_ROLE = '[APP] Add role'
ADD_ROLE = '[APP] Add role',
CLEAR_USER_ID = '[APP] Clear user id'
}
export class AddUserId implements Action {
@ -20,4 +20,13 @@ export class AddRole implements Action {
}
}
export type AppAction = AddUserId | AddRole;
export class ClearUserId implements Action {
readonly type = AppActionTypes.CLEAR_USER_ID;
constructor() {
}
}
export type AppAction = AddUserId | AddRole | ClearUserId;

View File

@ -0,0 +1,15 @@
import {Action} from "@ngrx/store";
export enum PlayerActionTypes {
ADD_CHARACTER_ID= '[PLAYER] Add character id'
}
export class AddCharacterId implements Action {
readonly type = PlayerActionTypes.ADD_CHARACTER_ID;
constructor(public payload: {characterId: number}) {
}
}
export type PlayerAction = AddCharacterId;

View File

@ -1,5 +1,15 @@
import {AppStoreModel} from './app-store.model';
import {ActionReducerMap} from '@ngrx/store';
import {AppReducer} from '../reducers/app.reducer';
import {PlayerStoreModel} from './player-store.model';
import {PlayerReducer} from '../reducers/player.reducer';
export interface AppState {
appState: AppStoreModel;
appStore: AppStoreModel;
playerStore: PlayerStoreModel;
}
export const reducers: ActionReducerMap<AppState> = {
appStore: AppReducer,
playerStore: PlayerReducer,
};

View File

@ -0,0 +1,3 @@
export interface PlayerStoreModel {
characterId: number;
}

View File

@ -12,6 +12,8 @@ export function AppReducer(state: AppStoreModel = initialState, action: AppActio
return {...state, userId: action.payload.userId};
case AppActionTypes.ADD_ROLE:
return {...state, role: action.payload.role};
case AppActionTypes.CLEAR_USER_ID:
return {...state, userId: null};
default:
return state;
}

View File

@ -0,0 +1,15 @@
import {PlayerStoreModel} from '../models/player-store.model';
import {PlayerAction, PlayerActionTypes} from '../actions/player.action';
const initialState: PlayerStoreModel = {
characterId: null
};
export function PlayerReducer(state: PlayerStoreModel = initialState, action: PlayerAction) {
switch (action.type) {
case PlayerActionTypes.ADD_CHARACTER_ID:
return {...state, characterId: action.payload.characterId};
default:
return state;
}
}

View File

@ -0,0 +1,14 @@
export enum scIcon {
Barbarian = 'barbarian',
Bard = 'bard',
Cleric = 'cleric',
Druid = 'druid',
Fighter = 'fighter',
Monk = 'monk',
Paladin = 'paladin',
Ranger = 'ranger',
rogue = 'rogue',
Sorcerer = 'sorcerer',
Warlock = 'warlock',
Wizard = 'wizard',
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M284.736 29.215c-2.334-.015-4.68.001-7.035.049-32.975.664-67.786 7.496-98.318 21.232-34.895 15.698-64.057 40.163-79.979 74.672-15 32.512-18.36 74.591-2.508 128.285a201.433 201.433 0 0 1 13.502-5.59c-9.866-43.961-5.617-80.245 8.301-109.01 15.464-31.958 42.464-54.15 72.95-68.302 30.484-14.153 64.583-20.494 95.738-20.95 1.947-.028 3.882-.035 5.804-.019 22.847.186 43.814 3.494 60.614 9.836 7.12-3.36 13.61-6.894 18.914-10.852-20.447-11.111-49.38-18.154-81.016-19.212a257.951 257.951 0 0 0-6.967-.14zm8.293 38.373c-1.78-.019-3.574-.015-5.379.012-28.88.421-60.75 6.43-88.421 19.277-27.671 12.847-51.013 32.303-64.327 59.818-11.852 24.495-16.052 55.773-7.242 95.895 12.372-2.904 23.747-3.494 33.565-1.195 9.93 2.325 18.916 9.147 21.732 19.312.306 1.106.52 2.235.701 3.373l102.203-102.203c-11.857-18.99-15.828-34.784-12.218-48.416 4.005-15.125 16.44-24.638 30.048-31.797 7.436-3.912 15.487-7.412 23.547-10.8-10.343-1.974-21.956-3.15-34.209-3.276zm83.057 68.326l-48.508 9.701-34.242 34.242h38.807v38.805l34.242-34.242zm87.348 3.367c-3.956 5.301-7.489 11.788-10.848 18.905 6.876 18.213 10.179 41.335 9.812 66.427-.455 31.155-6.796 65.254-20.949 95.739-14.153 30.485-36.344 57.485-68.303 72.949-28.764 13.918-65.048 18.167-109.01 8.3a201.436 201.436 0 0 1-5.59 13.503c53.695 15.852 95.774 12.492 128.286-2.508 34.51-15.922 58.974-45.084 74.672-79.979 15.698-34.894 22.379-75.376 21.142-112.32-1.058-31.637-8.1-60.569-19.212-81.016zm-22.297 45.48c-3.39 8.06-6.89 16.112-10.801 23.548-7.159 13.608-16.672 26.043-31.797 30.048-13.632 3.61-29.425-.361-48.416-12.218L247.92 328.342c1.138.181 2.267.395 3.373.701 10.165 2.816 16.987 11.802 19.312 21.732 2.3 9.818 1.709 21.193-1.195 33.565 40.122 8.81 71.4 4.61 95.895-7.242 27.515-13.314 46.971-36.656 59.818-64.327 12.847-27.67 18.856-59.542 19.277-88.421.208-14.228-1.004-27.742-3.263-39.588zm-160.528 13.096v33.534h33.534v-33.534zm-18 12.727l-34.244 34.244-9.699 48.506 48.506-9.7 34.244-34.243h-38.807zm-57.19 57.19l-37.034 37.035 38.806 38.806 37.036-37.035-48.508 9.701zm-49.76 49.761l-25.925 25.922 38.809 38.809 25.922-25.924zm-38.651 38.65L16 457.194V496h38.807l101.007-101.008z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M120.7 27.53l-28.93 8.56C112.1 187.8 125.6 321.9 183.9 455H228c-40-140.6-84.2-280.4-107.3-427.47zm19.9 10.36c2.6 16.05 5.5 32.03 8.7 47.95 9.8 2.67 19.9 6.9 30.1 11.85 18.3 8.71 37.3 19.81 56.1 29.51 18.8 9.7 37.3 17.9 53.6 21.1 16.4 3.2 29.8 1.7 41.6-7 22.2-16.4 38.4-26.2 51.3-31.4 12.8-5.2 23.3-5.9 31.6-1.8 7.8 4 11.5 11.1 14.2 17.1l5.1-11.3c-7.3-12.9-18.1-21.38-32.9-23.26-16.2-2.05-38.4 4.06-66 25.66-14.4 11.3-33 9.7-50.6 2.8-17.5-6.9-35.7-18.9-54.2-31.64-18.6-12.74-37.3-26.21-54.8-35.98-12.3-6.86-23.8-11.66-33.8-13.59zm12.8 68.31c4.8 23 10 45.9 15.6 68.7v-62.2c-5.4-2.6-10.6-4.8-15.6-6.5zM404.8 124c-27 110.6-55.1 223.8-97.7 331h38.6c34.5-94.4 51-203.5 70.3-311.3-1.8-3.8-3-7.4-4.3-10.4-2.3-5.3-4.3-8.1-6.3-9.1-.2-.1-.4-.2-.6-.2zM199 128.1v160.4c5.9 21.1 11.9 42.1 18 63.1V137.8c-6.1-3.2-12.1-6.5-18-9.7zM361 142c-5.4 3.6-11.4 7.8-18 12.6V288h1c5.9-20.9 11.5-41.8 17-62.8V142zm-114 10.8V455h18V160.2c-6-2.2-12-4.7-18-7.4zm66 14.3c-5.9.7-11.9.8-18 .2v269.8c6.3-16.4 12.3-32.9 18-49.6V167.1zM163.9 473l-15.1 16h214.4l-15.1-16H163.9z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M300.56 39.29c-2.418.023-5.135 1.13-7.27 3.065-2.137 1.935-3.507 4.53-3.77 6.932-.26 2.402.174 4.782 3.033 7.94l6.037 6.67 40.35 44.56 6.042 6.672c2.86 3.156 5.184 3.824 7.6 3.802 2.416-.023 5.135-1.13 7.272-3.065 2.136-1.934 3.506-4.53 3.767-6.93.262-2.404-.17-4.783-3.03-7.94L308.16 43.09c-2.86-3.158-5.185-3.823-7.6-3.8zm-15.31 36.69l-38.604 34.952-6.04-6.672c-23.138-25.555-36.56-26.794-53.106-27.586L23.285 225.364 151.018 366.43 315.23 217.74c.85-16.544.946-30.02-22.193-55.576l-6.04-6.672 38.6-34.953-40.347-44.56zm-112.146 54.276l33.86 37.396 37.397-33.86 19.66 21.714-37.393 33.86 33.86 37.396-21.714 19.662-33.86-37.397-95.3 86.29-19.664-21.713 95.302-86.29-33.86-37.396 21.712-19.662zm197.378 4.363s-25.86 52.77-16 73.81c6.237 13.306 25.764 13.306 32 0 9.862-21.04-16-73.81-16-73.81zm2.196 103.02l-5.655 46.28c1.168-.316 2.47-.504 3.967-.504 2.408 0 4.445.504 6.23 1.307l-4.542-47.082zm-58.967 15l28.087 66.067c2.457-5.83 5.08-11.178 7.744-15.855l-35.83-50.213zm117.536 1.497l-37.244 49.48c2.66 4.666 5.212 9.943 7.568 15.662l29.676-65.143zM270.143 295.11l63.375 47.704c.57-2.11 1.164-4.208 1.8-6.275 1.07-3.48 2.227-6.874 3.446-10.17l-68.62-31.26zm203.572 2.595l-69.135 29.39c1.103 3.1 2.144 6.29 3.104 9.546.665 2.257 1.273 4.55 1.855 6.858l64.175-45.793zm-102.32 4.95c-1.514 1.696-3.56 4.516-5.706 8.193-4.528 7.762-9.47 18.968-13.167 30.984-3.697 12.016-6.155 24.906-6.185 35.992-.03 11.087 2.422 19.947 6.97 25.225 2.532 2.935 9.886 5.884 17.682 5.884 7.796 0 15.153-2.95 17.684-5.885 4.597-5.335 7.19-14.28 7.344-25.376.154-11.097-2.07-23.966-5.6-35.945-3.53-11.98-8.384-23.133-12.965-30.798-2.252-3.768-4.46-6.66-6.058-8.276zm-38.727 43.402l-79.022 7.62 75.75 9.26c.754-5.654 1.88-11.318 3.272-16.88zm77.754 1.045c1.273 5.56 2.263 11.213 2.88 16.845l75.413-7.275-78.293-9.57zm-81.756 22.716l-60.02 42.828 60.15-25.57c-.322-3.063-.467-6.175-.458-9.303.007-2.63.122-5.286.328-7.955zm85.225 1.516c.107 2.21.156 4.41.126 6.59-.05 3.527-.286 7.03-.752 10.46l58.957 26.856-58.33-43.906zm-79.935 34.746l-22.84 50.135 30-39.858c-.494-.498-.973-1.016-1.44-1.556-2.315-2.685-4.193-5.616-5.72-8.72zm73.358 1.434c-1.403 2.574-3.05 5.02-5.004 7.287-.782.907-1.615 1.737-2.474 2.526l28.816 40.385-21.34-50.196zm-42.073 19.144l4.444 46.05 5.613-45.92c-1.436.1-2.876.146-4.307.146-1.912 0-3.835-.094-5.75-.276z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M257.563 25.156c353.16 276.87 16.918 408.895-87.875 293.25l-40.75 37.125 50.812 50.345c217.562 181.363 524.73-252.058 77.813-380.72zM110.75 364.28c-5.525 1.065-8.975 2.957-11.313 5.25-1.956 1.922-3.248 4.556-4.25 7.564l55.188 52.844c5.468-1.008 9.264-2.796 11.28-4.688 1.997-1.872 3.095-3.864 3.095-7.53l-54-53.44zm-24.72 30.314L30.407 445.28C13.67 472.28 45.1 506.478 81.5 489.94l51.53-50.282-47-45.062z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 521 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#fff" d="M66.54 18.002c-.327-.007-.655-.005-.98.006-4.064.136-8.105 1.634-11.39 4.535-7.508 6.632-8.218 18.094-1.586 25.602 4.394 4.974 10.906 6.945 16.986 5.792l57.838 65.475-50.373 44.498 24.188 27.38c9.69-21.368 22.255-39.484 37.427-54.65l6.91 36.188c25.092-6.29 49.834-10.563 74.366-12.873l-23.912-27.07-38.66-12.483c17.117-12.9 36.734-22.97 58.62-30.474l-24.19-27.385-50.37 44.496-57.92-65.57c1.79-5.835.617-12.43-3.72-17.34-3.498-3.96-8.34-6.03-13.235-6.128zm384.397 0c-4.895.1-9.735 2.168-13.232 6.127-4.338 4.91-5.514 11.506-3.723 17.343l-57.92 65.568-50.37-44.497-24.188 27.385c21.884 7.504 41.5 17.573 58.62 30.472l-38.66 12.485-23.255 26.324c24.71 1.863 49.367 5.706 74.118 11.46l6.498-34.03c15.173 15.166 27.74 33.282 37.43 54.65l24.185-27.38-50.372-44.498 57.838-65.475c6.08 1.153 12.593-.818 16.987-5.792 6.63-7.508 5.92-18.97-1.586-25.602-3.285-2.9-7.326-4.4-11.39-4.535-.326-.01-.653-.013-.98-.006zm-186.425 158.51c-39.56-.098-79.467 5.226-120.633 16.095-2.046 90.448 34.484 209.35 118.47 259.905 81.295-49.13 122.402-169.902 120.552-259.914-39.75-10.496-78.91-15.988-118.39-16.086zm-117.176 153.5L60.47 428.35l-12.2 63.894 61.9-19.994 68.49-77.535c-12.86-20.108-23.246-42.03-31.324-64.703zm228.203 6.11c-8.69 22.238-19.577 43.634-32.706 63.142l64.473 72.986 61.898 19.994-12.2-63.894-81.466-92.23z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M329.8 235.69l62.83-82.71 42.86 32.56-62.83 82.75zm-12.86-9.53l66.81-88-45-34.15-66.81 88zm-27.48-97.78l-19.3 39.57 57-75-42.51-32.3-36.24 47.71zm-20.74-73.24l-46.64-35.43-42 55.31 53.67 26.17zm107 235.52l-139-102.71-9.92.91 4.56 2 62.16 138.43-16.52 2.25-57.68-128.5-40-17.7-4-30.84 39.41 19.42 36.36-3.33 17-34.83-110.9-54.09-80.68 112.51L177.6 346.67l-22.7 145.62H341V372.62l35.29-48.93L387 275.77z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 518 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M107.3 26c-4.146 0-8.6 22.976-13.214 42.934l32.187 100.97-39.052-69.726c-2.932 14.342-5.414 28.62-7.002 42.771l43.176 58.246-44.838-36.824c-.435 11.08-.15 22.056 1.078 32.897l45.515 36.597-40.89-13.285c2.558 9.025 5.94 18.077 9.812 27.049l40.819 26.943-30.065-4.312c13.83 26.954 29.823 52.218 38.697 72.506 2.565 5.13 8.023 16.754 10.926 28.168 3.89 15.695-4.529 35.939-21.271 38.322 12.285-14.291 13.245-23.507 11.02-32.535-13.242-.192-19.112 15.916-19.112 15.916s-12.527 23.473 15.717 59.369c28.244 35.895 67.176 33.974 67.176 33.974s-2.243-55.044-1.036-79.96c1.22-25.165 8.354-69.758 8.354-69.758s-19.998.093-42.443-15.8c-28.167-19.942-17.51-32.621-24.663-51.077-14.417-37.201-4.68-95.143-4.68-95.143s-10.858-42.59-17.85-72.822C119.864 76.366 110.398 26 107.3 26zm297.4 0c-3.099 0-12.565 50.366-18.36 75.42-6.993 30.232-17.852 72.822-17.852 72.822s9.738 57.942-4.68 95.143c-7.152 18.456 3.505 31.135-24.662 51.078-22.445 15.892-42.443 15.8-42.443 15.8s7.134 44.592 8.354 69.757c1.207 24.916-1.036 79.962-1.036 79.962s38.932 1.92 67.176-33.976 15.717-59.37 15.717-59.37-5.87-16.107-19.111-15.915c-2.226 9.028-1.266 18.246 11.02 32.537-16.743-2.383-25.162-22.629-21.272-38.324 2.903-11.414 8.361-23.037 10.926-28.168 8.874-20.288 24.868-45.552 38.699-72.506l-30.067 4.312 40.819-26.943c3.872-8.972 7.254-18.024 9.812-27.049l-40.89 13.285 45.515-36.597c1.228-10.84 1.513-21.817 1.078-32.897l-44.838 36.824 43.176-58.246c-1.588-14.15-4.07-28.429-7.002-42.771l-39.052 69.726 32.187-100.968C413.3 48.978 408.846 26 404.7 26zm-148.702.463c-19.388 0-64.1 45.402-88.344 75.728-7.017 8.779-15.795 29.823-15.795 29.823l9.194 37.289s-1.154 8.452-2.604 30.49c-1.091 16.591-1.054 32.803-1.054 32.803l52.677-16.893c4.003-22.545 11.506-52.087 20.246-77.21 7.007-20.141 25.68-58.575 25.68-58.575s19.2 36.655 26.072 56.107c9.115 25.801 15.807 57.482 19.856 79.678l52.678 16.893s.036-16.212-1.055-32.803c-1.45-22.038-2.604-30.49-2.604-30.49l9.194-37.29s-6.09-19.371-12.035-27.349c-24.096-32.334-72.718-78.201-92.106-78.201zm.002 77.09s-10.719 28.18-15.37 50.697c-4.299 20.818-11.898 66.635-11.898 66.635s11.983 11.928 5.682 18.256c-6.301 6.328-17.043-5.705-17.043-5.705l-56.435 17.128 3.337 13.217 53.098 19.854s10.656-12.118 17.043-5.703c6.388 6.414-5.682 23.959-5.682 23.959s3.879 16.06 5.995 24.045c3.45 13.022 10.927 38.908 10.927 38.908l10.344 2.867 10.346-2.867s6.8-24.203 10.047-36.346c2.366-8.85 6.875-26.607 6.875-26.607s-12.07-17.545-5.682-23.96c6.388-6.414 17.043 5.704 17.043 5.704l53.098-19.854 3.337-13.217-56.435-17.128s-10.742 12.033-17.043 5.705c-6.301-6.328 5.682-18.256 5.682-18.256s-7.547-42.316-11.897-65.81C267.12 132.121 256 103.552 256 103.552zm0 136.369c5.02 0 9.088 8.172 9.088 18.254 0 10.081-4.068 18.256-9.088 18.256s-9.09-8.175-9.09-18.256c0-10.082 4.07-18.254 9.09-18.254z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M114.4 35.99l36.8 85.91c4 2.4 7.9 4.9 11.8 7.5V66.55c-16-11.07-32.2-21.32-48.6-30.56zM181 50.56V160c0 .2.7 2.4 3.4 4.9 2.7 2.5 6.9 5.1 10.9 6.7 3.2 1.3 5.9 1.7 7.7 1.8V64c0-.25-.7-2.39-3.4-4.92s-6.9-5.11-10.9-6.72c-3.2-1.26-5.9-1.69-7.7-1.8zm40 60.54v63.2c48.3 43.4 88.2 95.2 118.7 145 22.3 36.5 39.5 71.9 51.2 102.5 9.9 25.8 16 47.9 17.6 65.2h93.1c-3.4-15.2-13.9-41.6-31-72.9-21.2-38.8-52-85.9-89.7-134.6C336 221.7 281.2 161.7 221 111.1zm-38 74.7V486h18V191.5c-4.2-.3-8.3-1.5-12.3-3.1-1.9-.8-3.8-1.7-5.7-2.6z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 626 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" ><path d="M254.1 18.63c-81.4 0-231.43 155.97-171.63 300.77 8 25.3 27.83 50.4 49.13 77.1 24.4 30.6 51.6 63.2 68.7 96.9h20.5c-18.1-39.8-48.5-75.9-74.6-108.6-27.4-34.3-48.73-65.2-48.73-87.9.1-9.1 2.23-18.1 5.53-26.3 23-61.4 114-119.7 148.5-135l3.6-2 3.9 1.3c60.9 20.9 129.3 66.7 154 135.7 4.1 11.7 5.9 18 5.6 27.3-.5 15.8-24.5 54.7-55 88.7-29.1 32.4-62.4 67.7-80 106.7h20.5c16.8-32.2 46.2-64 73.3-94.2 23.2-25.6 45.3-50 54.9-74.8 52.9-124-99.2-305.67-178.2-305.67zm.8 135.47c-38.7 21.5-85.1 52.2-113.7 88.2 9.7 83 59 146.1 118.3 146.1 59.2 0 108.3-62.7 118.2-145.3-28.9-42.1-78-72.9-122.8-89zm-58.3 83h2.4c13.1.1 26.1 2.7 39.1 7.4-16.8 40.6-59 42-78.1 0 12.2-4.8 24.4-7.2 36.6-7.4zm124.9 0c13-.1 26 2.3 39.1 7.4-19.2 42-61.3 40.6-78.2 0 13.1-4.7 26.1-7.3 39.1-7.4z" fill="#fff" fill-opacity="1"></path></svg>

After

Width:  |  Height:  |  Size: 868 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M166 121c0 90 90 105 90 180 0 30-30 75-75 75s-75-45-45-120c-45 30-60 60-60 90 0 75 75 150 180 150s180-45 180-135c.67-133.125-153.4-177.596-195-240-30-45-15-75 15-105-60 15-90 57-90 105z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#fff" d="M256 16l-32 112 32 32 32-32-32-112zM64 96l32 80 64 16-96-96zm384 0l-96 96 64-16 32-80zm-192 80l-64 48-128 32c80 16 128 96 192 128 64-32 112.476-110.213 192-128l-128-28.31L256 176zm-39.512 52.682l28.342 8.863-7.45 20.955L256 310.895l18.62-52.395-7.45-20.955 28.342-8.863c14.923 10.97 24.488 28.03 24.488 47.283C320 309.237 291.47 336 256 336s-64-26.763-64-60.035c0-19.254 9.565-36.314 24.488-47.283zM96 336l-64 48-16 64 32-32 64-48s-16-27.61-16-32zm320 0l-16 32 64 48 32 32-16-64-64-48zm-272 64l-16 64 48-48-32-16zm112 0l-48 16 48 80 48-80-48-16zm112 0l-32 16 48 48-16-64z"/></svg>

After

Width:  |  Height:  |  Size: 664 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M335.656 19.53c-24.51.093-48.993 5.235-71.062 15.626-22.46 10.577-43.112 34.202-58.375 62.563-15.264 28.36-25.182 61.262-27.69 88.75-7.487 82.112-51.926 155.352-159.78 252.56l-.188 21.44C89.216 403.443 139.915 346.632 176.313 290l.063.03c-9.293 32.473-22.623 63.18-43.594 87.97-31.47 35.584-69.222 71.1-114.468 106.53l-.062 8.25 25 .064h.47l1.28-1.156c24.405-16.498 48.607-31.488 72.594-41.5l.187.187-46.436 42.5 28.937.063c48.372-41.685 94.714-90.58 129.626-137 33.587-44.658 56.02-87.312 60.688-116.844-1.268-2.32-2.552-4.628-3.656-7.094-18.833-42.06-4.273-96.424 40.218-116.063 32.73-14.45 74.854-3.165 90.438 31.344.15.333.324.634.47.97 13.302 24.062 6.175 49.48-9.345 61.97-7.866 6.328-18.442 9.528-28.75 6.56-10.31-2.966-19.043-11.772-24.5-25.124l17.28-7.062c3.992 9.764 8.667 13.15 12.375 14.22 3.708 1.066 7.767.148 11.875-3.158 8.216-6.61 14.282-21.91 4.406-39.03l-.28-.47-.22-.5c-10.7-24.82-41.96-33.333-66.22-22.625-34.063 15.037-45.594 58.052-30.686 91.345 20.527 45.846 77.97 61.177 122.375 40.875 60.157-27.5 80.13-103.328 53.094-161.813-24.737-53.503-81.41-82.484-138.908-83.843-1.633-.04-3.272-.07-4.906-.063zm-25.75 26.72c3.238.035 6.363.348 9.406.906 10.343 1.898 19.946 6.753 29.032 13.25-30.623-5.437-58.324 4.612-80.78 24.782-22.44 20.152-39.16 50.59-45.783 84.718-4.655-11.358-7.166-21.462-6.686-31.72.296-6.343 1.715-12.956 4.78-20.217 9.094-18.016 21.032-33.946 35.22-46.69 7.824-7.026 16.39-13.07 25.53-17.905 10.932-5.212 20.522-7.22 29.282-7.125zm122.938 62.313c22.583 13.167 34.365 41.86 32.937 70.656-.564 11.395-3.466 22.975-8.905 33.624-12.48 18.937-35.53 25.51-49.97 20.875l-.092-.25c27.943-10.365 39.18-32.377 40.312-55.19.124-2.5.115-4.994-.03-7.468 1.447-13.31-.412-28.793-5.47-43.437-2.244-6.496-5.15-12.89-8.844-18.72l.064-.093zm-135.563 1.312c-20.97 19.342-29.406 35.252-33.25 51.25-3.848 16.023-2.788 32.84-2.905 52.875-.14 23.79-2.56 51.542-18.438 85.688-.005.012-.025.018-.03.03-21.095 26.753-45.276 52.25-68.907 67.376l-.063-.03c64.195-71.545 68.527-114.792 68.75-153.19.112-19.197-1.253-37.594 3.438-57.124.57-2.37 1.233-4.742 2-7.125h.03c8.098-17.036 16.572-26.058 25.47-31.563 7.18-4.44 15.035-6.697 23.906-8.187z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Some files were not shown because too many files have changed in this diff Show More