Skip to content

Commit

Permalink
X2CommunityCore#275 Refactored and fixes. Makes recalculating optiona…
Browse files Browse the repository at this point in the history
…l for bulk add and recalc at the end
  • Loading branch information
Musashi1584 committed Aug 19, 2017
1 parent dfa0c75 commit 84b2f94
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 50 deletions.
10 changes: 5 additions & 5 deletions X2CommunityHighlander.XCOM_sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# XCOM ModBuddy Solution File, Format Version 11.00
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{5DAE07AF-E217-45C1-8DE7-FF99D6011E8A}") = "X2CommunityHighlander", "X2CommunityHighlander\X2CommunityHighlander.x2proj", "{7D66C20E-7B03-407E-A6C7-9FA1F14BE188}"
Project("{5DAE07AF-E217-45C1-8DE7-FF99D6011E8A}") = "X2CommunityHighlander", "X2CommunityHighlander\X2CommunityHighlander.x2proj", "{AD0ECFCE-FC7E-4473-9925-A75338E1E8E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|XCOM 2 = Debug|XCOM 2
Default|XCOM 2 = Default|XCOM 2
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7D66C20E-7B03-407E-A6C7-9FA1F14BE188}.Debug|XCOM 2.ActiveCfg = Debug|XCOM 2
{7D66C20E-7B03-407E-A6C7-9FA1F14BE188}.Debug|XCOM 2.Build.0 = Debug|XCOM 2
{7D66C20E-7B03-407E-A6C7-9FA1F14BE188}.Default|XCOM 2.ActiveCfg = Debug|XCOM 2
{7D66C20E-7B03-407E-A6C7-9FA1F14BE188}.Default|XCOM 2.Build.0 = Debug|XCOM 2
{AD0ECFCE-FC7E-4473-9925-A75338E1E8E9}.Debug|XCOM 2.ActiveCfg = Debug|XCOM 2
{AD0ECFCE-FC7E-4473-9925-A75338E1E8E9}.Debug|XCOM 2.Build.0 = Debug|XCOM 2
{AD0ECFCE-FC7E-4473-9925-A75338E1E8E9}.Default|XCOM 2.ActiveCfg = Debug|XCOM 2
{AD0ECFCE-FC7E-4473-9925-A75338E1E8E9}.Default|XCOM 2.Build.0 = Debug|XCOM 2
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
163 changes: 118 additions & 45 deletions X2CommunityHighlander/Src/XComGame/Classes/X2LootTable.uc
Original file line number Diff line number Diff line change
Expand Up @@ -17,75 +17,103 @@ native function InitLootTables(bool bValidateItemNames=true); // validates loo
native function RollForLootTable(const out name LootTableName, out array<name> RolledLoot);

// Start Issue #275 - Add a loot table interface
// static function are for use in the DLCInfo OnPostTemplatesCreated event
public function AddEntry(name TableName, LootTableEntry TableEntry)
public function AddLootTable(LootTable AddLootTable)
{
AddEntryIntern(self, TableName, TableEntry);
AddLootTableIntern(self, AddLootTable);
}

public function RemoveEntry(name TableName, LootTableEntry TableEntry)
public function RemoveLootTable(LootTable LootTable)
{
RemoveEntryIntern(self, TableName, TableEntry);
LootTables.RemoveItem(LootTable);
}

public function AddLootTable(LootTable AddLootTable)
public function AddEntry(name TableName, LootTableEntry TableEntry, optional bool bRecalculateChances = true)
{
local LootTableEntry Loot;
foreach AddLootTable.Loots(Loot)
{
AddEntryIntern(self, AddLootTable.TableName, Loot);
}
AddEntryIntern(self, TableName, TableEntry, bRecalculateChances);
}

public function RemoveLootTable(LootTable LootTable)
public function RemoveEntry(name TableName, LootTableEntry TableEntry, optional bool bRecalculateChances = true)
{
RemoveEntryIntern(self, TableName, TableEntry, bRecalculateChances);
}
// Recalculate chances for an entire loot table
public function RecalculateLootTableChance(name TableName)
{
RemoveLootTable(LootTable);
RecalculateLootTableChanceIntern(self, TableName);
}

// **************************************************
// Static function
// Should be used before Loot Tables are initialized
// e.g. OnPostTemplatesCreated
// **************************************************
public static function AddLootTableStatic(LootTable AddLootTable)
{
local X2LootTable LootTable;
local LootTableEntry Loot;

LootTable = X2LootTable(class'Engine'.static.FindClassDefaultObject(string(default.Class.Name)));
foreach AddLootTable.Loots(Loot)
{
AddEntryIntern(LootTable, AddLootTable.TableName, Loot);
}
AddLootTableIntern(GetX2LootTableCDO(), AddLootTable);
}

public static function RemoveLootTableStatic(LootTable RemoveLootTable)
{
local X2LootTable LootTable;

LootTable = X2LootTable(class'Engine'.static.FindClassDefaultObject(string(default.Class.Name)));
LootTable = GetX2LootTableCDO();
LootTable.LootTables.RemoveItem(RemoveLootTable);
}

public static function AddEntryStatic(name TableName, LootTableEntry AddTableEntry)
public static function AddEntryStatic(name TableName, LootTableEntry AddTableEntry, optional bool bRecalculateChances = true)
{
local X2LootTable LootTable;
AddEntryIntern(GetX2LootTableCDO(), TableName, AddTableEntry, bRecalculateChances);
}

LootTable = X2LootTable(class'Engine'.static.FindClassDefaultObject(string(default.Class.Name)));
AddEntryIntern(LootTable, TableName, AddTableEntry);
public static function RemoveEntryStatic(name TableName, LootTableEntry TableEntry, optional bool bRecalculateChances = true)
{
RemoveEntryIntern(GetX2LootTableCDO(), TableName, TableEntry, bRecalculateChances);
}

public static function RemoveEntryStatic(name TableName, LootTableEntry TableEntry)
// Recalculate chances for an entire loot table
public static function RecalculateLootTableChanceStatic(name TableName)
{
local X2LootTable LootTable;
LootTable = X2LootTable(class'Engine'.static.FindClassDefaultObject(string(default.Class.Name)));
RemoveEntryIntern(LootTable, TableName, TableEntry);
RecalculateLootTableChanceIntern(GetX2LootTableCDO(), TableName);
}

// **************************************************
// Private function
// **************************************************
private static function X2LootTable GetX2LootTableCDO()
{
return X2LootTable(class'Engine'.static.FindClassDefaultObject(string(default.Class.Name)));
}

private static function AddLootTableIntern(X2LootTable LootTable, LootTable AddLootTable)
{
local LootTableEntry LootEntry;

if (LootTable.LootTables.Find('TableName', AddLootTable.TableName) == INDEX_NONE)
{
LootTable.LootTables.AddItem(AddLootTable);

foreach AddLootTable.Loots(LootEntry)
{
AddEntryIntern(LootTable, AddLootTable.TableName, LootEntry, false);
}

RecalculateLootTableChanceIntern(LootTable, AddLootTable.TableName);
}
}

private static function RemoveEntryIntern(X2LootTable LootTable, name TableName, LootTableEntry TableEntry)
private static function RemoveEntryIntern(
X2LootTable LootTable,
name TableName,
LootTableEntry TableEntry,
bool bRecalculateChances)
{
local int Index, EntryIndex;

Index = LootTable.LootTables.Find('TableName', TableName);

if (Index != INDEX_NONE)
{
for (EntryIndex = 0; EntryIndex < LootTable.LootTables[Index].Loots.Length; EntryIndex++)
for (EntryIndex = LootTable.LootTables[Index].Loots.Length -1; EntryIndex >= 0; EntryIndex--)
{
if (LootTable.LootTables[Index].Loots[EntryIndex].RollGroup == TableEntry.RollGroup &&
LootTable.LootTables[Index].Loots[EntryIndex].TemplateName == TableEntry.TemplateName &&
Expand All @@ -95,34 +123,62 @@ private static function RemoveEntryIntern(X2LootTable LootTable, name TableName,
// Remove the table entry
LootTable.LootTables[Index].Loots.Remove(EntryIndex, 1);
// Recalculate the chances for the roll group
RecalculateChances(LootTable, Index, TableEntry.RollGroup);
break;
if (bRecalculateChances)
RecalculateChancesForRollGroup(LootTable, Index, TableEntry.RollGroup);
}
}
}
}

private static function AddEntryIntern(X2LootTable LootTable, name TableName, LootTableEntry TableEntry)
private static function AddEntryIntern(
X2LootTable LootTable,
name TableName,
LootTableEntry TableEntry,
bool bRecalculateChances)
{
local int Index;

Index = LootTable.LootTables.Find('TableName', TableName);

if (Index != INDEX_NONE)
if (Index != INDEX_NONE && TableEntry.Chance <= 100 && TableEntry.Chance > 0)
{
// Add the new table entry
LootTable.LootTables[Index].Loots.AddItem(TableEntry);

// Recalculate the chances for the roll group
RecalculateChances(LootTable, Index, TableEntry.RollGroup);
if (bRecalculateChances)
RecalculateChancesForRollGroup(LootTable, Index, TableEntry.RollGroup);
}
}

private static function RecalculateLootTableChanceIntern(X2LootTable LootTable, name TableName)
{
local LootTableEntry TableEntry;
local array<int> RollGroups;
local int Index, RollGroup;

Index = LootTable.LootTables.Find('TableName', TableName);
if (Index != INDEX_NONE)
{
foreach LootTable.LootTables[Index].Loots(TableEntry)
{
if (RollGroups.Find(TableEntry.RollGroup) == INDEX_NONE)
{
RollGroups.AddItem(TableEntry.RollGroup);
}
}

foreach RollGroups(RollGroup)
{
RecalculateChancesForRollGroup(LootTable, Index, RollGroup);
}
}
}

// When the sum of chances is unequal 100% after adding/removing an entry, recalculate chances to 100% total
static function RecalculateChances(X2LootTable LootTable, int Index, int RollGroup)
private static function RecalculateChancesForRollGroup(X2LootTable LootTable, int Index, int RollGroup)
{
local LootTableEntry TableEntry;
local int OldChance, NewChance, SumChances, NewSumChances, TableEntryIndex;
local int OldChance, NewChance, SumChances, NewSumChances, TableEntryIndex, RoundDiff, DiffIndex;

foreach LootTable.LootTables[Index].Loots(TableEntry)
{
Expand All @@ -139,16 +195,33 @@ static function RecalculateChances(X2LootTable LootTable, int Index, int RollGro
OldChance = LootTable.LootTables[Index].Loots[TableEntryIndex].Chance;
NewChance = Round(100 / SumChances * OldChance);

// Add round based differences to the last entry
NewSumChances += NewChance;
if(TableEntryIndex == LootTable.LootTables[Index].Loots.Length - 1 && NewSumChances != 100)
{
NewChance += (100 - NewSumChances);
}

LootTable.LootTables[Index].Loots[TableEntryIndex].Chance = NewChance;
}
}
// even out round based differences
RoundDiff = (100 - NewSumChances);
NewSumChances = 0;
TableEntryIndex = 0;
for (TableEntryIndex = 0; TableEntryIndex < LootTable.LootTables[Index].Loots.Length; TableEntryIndex++)
{
if (LootTable.LootTables[Index].Loots[TableEntryIndex].RollGroup == RollGroup)
{
if (RoundDiff > 0)
{
LootTable.LootTables[Index].Loots[TableEntryIndex].Chance += 1;
RoundDiff--;
}
else if (RoundDiff < 0)
{
LootTable.LootTables[Index].Loots[TableEntryIndex].Chance -= 1;
DiffIndex++;
}
NewSumChances += LootTable.LootTables[Index].Loots[TableEntryIndex].Chance;
}
}
LootTable.LootTables[Index].Loots[0].Chance += (100 - NewSumChances);
}
}
// End Issue #275

0 comments on commit 84b2f94

Please sign in to comment.