Skip to content

Commit

Permalink
Version 0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Grauenwolf committed Jul 27, 2017
1 parent 73f8829 commit ca6e94e
Show file tree
Hide file tree
Showing 6 changed files with 389 additions and 32 deletions.
149 changes: 139 additions & 10 deletions SavageTools/SavageTools.Shared/CharacterGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,19 @@ public async Task<Character> GenerateCharacterAsync()
}

//Main loop for random picks
while (result.UnusedAttributes > 0 || result.UnusedSkills > 0 || result.UnusedSmartSkills > 0 || result.UnusedAdvances > 0 || result.UnusedEdges > 0 || result.UnusedHindrances > 0)
while (result.UnusedAttributes > 0 || result.UnusedSkills > 0 || result.UnusedSmartSkills > 0 || result.UnusedAdvances > 0 || result.UnusedEdges > 0 || result.UnusedHindrances > 0 || result.UnusedRacialEdges > 0 || result.UnusedIconicEdges > 0)
{
//tight loop to apply current hindrances
while (result.UnusedHindrances > 0)
PickHindrance(result, dice);

//Pick up racial and iconic edges early because they can grant skills
if (result.UnusedRacialEdges > 0)
PickRacialEdge(result, dice);

if (result.UnusedIconicEdges > 0)
PickIconicEdge(result, dice);

if (result.UnusedAttributes > 0)
PickAttribute(result, dice);

Expand Down Expand Up @@ -276,17 +283,37 @@ void ApplyArchetype(Character result, Dice dice)
if (SelectedArchetype.Traits != null)
foreach (var item in SelectedArchetype.Traits)
result.Increment(item.Name, item.Bonus, dice);

}
void ApplyRace(Character result, Dice dice)
{
//Add the race
result.Race = SelectedRace.Name;

if (SelectedRace.Edges != null)
foreach (var item in SelectedRace.Edges)
ApplyEdge(result, FindEdge(item), dice);

if (SelectedRace.Hindrances != null)
foreach (var item in SelectedRace.Hindrances)
{
//Lookup the edge defintion. If not found, assume this edge is custom for the race.
var edge = Edges.SingleOrDefault(e => e.Name == item.Name) ?? item;
ApplyEdge(result, edge, dice);
//pick up the level from the archetype
var level = 0;
if (item.Type == "Minor" || item.Type == "Minor/Major")
level = 1;
else if (item.Type == "Major")
level = 2;

var hindrance = FindHindrance(item);

if (level == 0) //check for a default
{
if (hindrance.Type == "Minor" || hindrance.Type == "Minor/Major")
level = 1;
else if (hindrance.Type == "Major")
level = 2;
}
ApplyHindrance(result, hindrance, level, dice);
}

if (SelectedRace.Skills != null)
Expand All @@ -301,6 +328,12 @@ void ApplyRace(Character result, Dice dice)
if (SelectedRace.Traits != null)
foreach (var item in SelectedRace.Traits)
result.Increment(item.Name, item.Bonus, dice);

if (SelectedRace.Powers != null)
foreach (var item in SelectedRace.Powers)
AddPower(result, item, dice);


}
void ApplyHindrance(Character result, SettingHindrance hindrance, int level, Dice dice)
{
Expand Down Expand Up @@ -568,15 +601,15 @@ static void PickAttribute(Character result, Dice dice)
{
//Attributes are likely to stack rather than spread evenly
var table = new Table<string>();
if (result.Vigor < 12)
if (result.Vigor < result.MaxVigor)
table.Add("Vigor", result.Vigor.Score);
if (result.Smarts < 12)
if (result.Smarts < result.MaxSmarts)
table.Add("Smarts", result.Smarts.Score);
if (result.Agility < 12)
if (result.Agility < result.MaxAgility)
table.Add("Agility", result.Agility.Score);
if (result.Strength < 12)
if (result.Strength < result.MaxStrength)
table.Add("Strength", result.Strength.Score);
if (result.Spirit < 12)
if (result.Spirit < result.MaxSpirit)
table.Add("Spirit", result.Spirit.Score);

result.Increment(table.RandomChoose(dice), dice);
Expand Down Expand Up @@ -630,11 +663,42 @@ void PickPower(Character result, PowerGroup group, Dice dice)
group.UnusedPowers -= 1;
}

void AddPower(Character result, SettingPower power, Dice dice)
{
var trappings = new List<SettingTrapping>();
var group = result.PowerGroups[power.Skill];

foreach (var item in Trappings)
{
if (group.AvailableTrappings.Count > 0 && !group.AvailableTrappings.Contains(item.Name))
continue;

if (group.ProhibitedTrappings.Contains(item.Name))
continue;

trappings.Add(item);
}

if (trappings.Count == 0)
trappings.Add(new SettingTrapping() { Name = "None" });

var trapping = dice.Choose(Trappings);

group.Powers.Add(new Power(power.Name, trapping.Name));
}


void PickEdge(Character result, Dice dice)
{
var table = new Table<SettingEdge>();
foreach (var item in Edges)
var edgeList = (IEnumerable<SettingEdge>)Edges;

if (SelectedArchetype.IconicEdges != null)
edgeList = edgeList.Concat(SelectedArchetype.IconicEdges);
if (SelectedRace.RacialEdges != null)
edgeList = edgeList.Concat(SelectedRace.RacialEdges);

foreach (var item in edgeList)
{
//TODO: Some edges allow duplicates
if (result.Edges.Any(e => e.Name == item.Name))
Expand All @@ -661,6 +725,71 @@ void PickEdge(Character result, Dice dice)
result.UnusedEdges -= 1;
}
}

void PickRacialEdge(Character result, Dice dice)
{
var table = new Table<SettingEdge>();

foreach (var item in SelectedRace.RacialEdges)
{
//TODO: Some edges allow duplicates
if (result.Edges.Any(e => e.Name == item.Name))
continue; //no dups

if (!string.IsNullOrEmpty(item.UniqueGroup))
if (result.Edges.Any(e => e.UniqueGroup == item.UniqueGroup))
continue; //can't have multiple from a unique group (i.e. arcane background)

var requirements = item.Requires.Split(',').Select(e => e.Trim());
if (requirements.All(c => result.HasFeature(c, BornAHero)))
table.Add(item, 1);
}
if (table.Count == 0)
{
Debug.WriteLine("No edges were available");
}
else
{
Debug.WriteLine($"Found {table.Count} edges");
var edge = table.RandomChoose(dice);
ApplyEdge(result, edge, dice);

result.UnusedRacialEdges -= 1;
}
}

void PickIconicEdge(Character result, Dice dice)
{
var table = new Table<SettingEdge>();

foreach (var item in SelectedArchetype.IconicEdges)
{
//TODO: Some edges allow duplicates
if (result.Edges.Any(e => e.Name == item.Name))
continue; //no dups

if (!string.IsNullOrEmpty(item.UniqueGroup))
if (result.Edges.Any(e => e.UniqueGroup == item.UniqueGroup))
continue; //can't have multiple from a unique group (i.e. arcane background)

var requirements = item.Requires.Split(',').Select(e => e.Trim());
if (requirements.All(c => result.HasFeature(c, BornAHero)))
table.Add(item, 1);
}
if (table.Count == 0)
{
Debug.WriteLine("No edges were available");
}
else
{
Debug.WriteLine($"Found {table.Count} edges");
var edge = table.RandomChoose(dice);
ApplyEdge(result, edge, dice);

result.UnusedIconicEdges -= 1;
}
}

static void PickAdvancement(Character result, Dice dice)
{
result.UnusedAdvances -= 1;
Expand Down
17 changes: 17 additions & 0 deletions SavageTools/SavageTools.Shared/Characters/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ public class Character : ChangeTrackingModelBase
public Trait Spirit { get { return Get<Trait>(); } set { Set(value); } }
public Trait Vigor { get { return Get<Trait>(); } set { Set(value); } }



public Trait MaxAgility { get { return GetDefault<Trait>(12); } set { Set(value); } }
public Trait MaxSmarts { get { return GetDefault<Trait>(12); } set { Set(value); } }
public Trait MaxStrength { get { return GetDefault<Trait>(12); } set { Set(value); } }
public Trait MaxSpirit { get { return GetDefault<Trait>(12); } set { Set(value); } }
public Trait MaxVigor { get { return GetDefault<Trait>(12); } set { Set(value); } }

public SkillCollection Skills { get { return GetNew<SkillCollection>(); } }
public HindranceCollection Hindrances { get { return GetNew<HindranceCollection>(); } }
public EdgeCollection Edges { get { return GetNew<EdgeCollection>(); } }
Expand All @@ -26,6 +34,8 @@ public class Character : ChangeTrackingModelBase
public int UnusedSkills { get { return Get<int>(); } set { Set(value); } }
public int UnusedSmartSkills { get { return Get<int>(); } set { Set(value); } }
public int UnusedEdges { get { return Get<int>(); } set { Set(value); } }
public int UnusedRacialEdges { get { return Get<int>(); } set { Set(value); } }
public int UnusedIconicEdges { get { return Get<int>(); } set { Set(value); } }
public int UnusedHindrances { get { return Get<int>(); } set { Set(value); } }
public int UnusedAdvances { get { return Get<int>(); } set { Set(value); } }

Expand Down Expand Up @@ -77,6 +87,12 @@ public void Increment(string trait, int bonus, Dice dice)
case "Strength": Strength += bonus; return;
case "Spirit": Spirit += bonus; return;

case "MaxVigor": MaxVigor += bonus; return;
case "MaxSmarts": MaxSmarts += bonus; return;
case "MaxAgility": MaxAgility += bonus; return;
case "MaxStrength": MaxStrength += bonus; return;
case "MaxSpirit": MaxSpirit += bonus; return;

case "Pace": Pace += bonus; return;
case "Running": Running += bonus; return;
case "Charisma": Charisma += bonus; return;
Expand All @@ -90,6 +106,7 @@ public void Increment(string trait, int bonus, Dice dice)
case "UnusedSkills": UnusedSkills += bonus; return;
case "UnusedSmartSkills": UnusedSmartSkills += bonus; return;
case "UnusedEdges": UnusedEdges += bonus; return;
case "UnusedRacialEdges": UnusedRacialEdges += bonus; return;
case "UnusedHindrances": UnusedHindrances += bonus; return;
case "UnusedAdvances": UnusedAdvances += bonus; return;
case "PowerPoints": dice.Choose(PowerGroups).PowerPoints += bonus; return;
Expand Down
20 changes: 10 additions & 10 deletions SavageTools/SavageTools.Shared/SavageTools.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,34 +80,34 @@
<ItemGroup>
<None Include="packages.config" />
<None Include="Settings\Arcana.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Fantasy Companion.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Savage Foes of North America.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Rifts Tomorrow Legion.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Super Powers.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Weird Science.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Psionics.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Miracles.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Magic.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Settings\Core.savage-setting">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Expand Down
Loading

0 comments on commit ca6e94e

Please sign in to comment.