Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cloning AI Triggers for Easier Difficulties #195

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/TSMapEditor/Config/UI/Windows/AITriggersWindow.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ $CC02=lblAITriggers:XNALabel
$CC03=btnNew:EditorButton
$CC04=btnDelete:EditorButton
$CC05=btnClone:EditorButton
$CC06=lbAITriggers:EditorListBox
$CC07=lblSelectedAITrigger:XNALabel
$CC08=tbName:EditorTextBox
$CC09=lblName:XNALabel
$CC10=ddSide:XNADropDown
$CC11=lblSide:XNALabel
$CC12=ddHouseType:XNADropDown
$CC13=lblHouse:XNALabel
$CC06=ddActions:XNADropDown
$CC07=lbAITriggers:EditorListBox
$CC08=lblSelectedAITrigger:XNALabel
$CC09=tbName:EditorTextBox
$CC10=lblName:XNALabel
$CC11=ddSide:XNADropDown
$CC12=lblSide:XNALabel
$CC13=ddHouseType:XNADropDown
$CC14=lblHouse:XNALabel
$CCline1=panelLine1:XNAPanel
$CCc1=lblConditionHeader:XNALabel
$CCc2=ddConditionType:XNADropDown
Expand Down Expand Up @@ -91,10 +92,15 @@ $Y=getBottom(btnDelete) + VERTICAL_SPACING
$Width=getWidth(btnNew)
Text=Clone

[lbAITriggers]
[ddActions]
$X=getX(lblAITriggers)
$Y=getBottom(btnClone) + VERTICAL_SPACING
$Width=getWidth(btnNew)

[lbAITriggers]
$X=getX(lblAITriggers)
$Y=getBottom(ddActions) + VERTICAL_SPACING
$Width=getWidth(btnNew)
$Height=450

; ************************************************
Expand Down
20 changes: 20 additions & 0 deletions src/TSMapEditor/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,26 @@ public static IEnumerable<Point2D> GetFillAreaTiles(MapTile targetTile, Map map,
return tilesToProcess;
}

/// <summary>
/// Converts a name that includes a difficulty to instead have a different difficulty.
/// Useful for cloning purposes of any type of object named by users to additional difficulty levels.
/// </summary>
/// <param name="name">Original name to convert.</param>
/// <param name="fromDifficulty">Current difficulty to convert the name from (replace).</param>
/// <param name="toDifficulty">New difficulty to convert the name to (replace).</param>
/// <returns>New name after it was converted to the desired difficulty.</returns>
public static string ConvertNameToNewDifficulty(string name, Difficulty fromDifficulty, Difficulty toDifficulty)
{
string fromDifficultyString = fromDifficulty.ToString();
string toDifficultyString = toDifficulty.ToString();

string newName = name.Replace(fromDifficultyString, toDifficultyString);
newName = newName.Replace($" {fromDifficultyString[0]}", $" {toDifficultyString[0]}");
newName = newName.Replace($"{fromDifficultyString[0]} ", $"{toDifficultyString[0]} ");

return newName;
}

/// <summary>
/// Generates outline edges for a foundation of cells
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/TSMapEditor/Models/Enums/Difficulty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TSMapEditor.Models
{
public enum Difficulty
{
Easy,
Medium,
Hard
}
}
126 changes: 126 additions & 0 deletions src/TSMapEditor/UI/Windows/AITriggersWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public AITriggersWindow(WindowManager windowManager, Map map) : base(windowManag
public event EventHandler<TeamTypeEventArgs> TeamTypeOpened;

private EditorListBox lbAITriggers;
private XNADropDown ddActions;
private EditorTextBox tbName;
private XNADropDown ddSide;
private XNADropDown ddHouseType;
Expand Down Expand Up @@ -56,6 +57,7 @@ public override void Initialize()
base.Initialize();

lbAITriggers = FindChild<EditorListBox>(nameof(lbAITriggers));
ddActions = FindChild<XNADropDown>(nameof(ddActions));
tbName = FindChild<EditorTextBox>(nameof(tbName));
ddSide = FindChild<XNADropDown>(nameof(ddSide));
ddHouseType = FindChild<XNADropDown>(nameof(ddHouseType));
Expand Down Expand Up @@ -89,9 +91,133 @@ public override void Initialize()
var technoTypeDarkeningPanel = DarkeningPanel.InitializeAndAddToParentControlWithChild(WindowManager, Parent, selectTechnoTypeWindow);
technoTypeDarkeningPanel.Hidden += TechnoTypeDarkeningPanel_Hidden;

ddActions.AddItem("Advanced...");
ddActions.AddItem(new XNADropDownItem() { Text = "Clone for Easier Difficulties", Tag = new Action(CloneForEasierDifficulties) });
ddActions.SelectedIndex = 0;
ddActions.SelectedIndexChanged += DdActions_SelectedIndexChanged;

lbAITriggers.SelectedIndexChanged += LbAITriggers_SelectedIndexChanged;
}

private void CloneForEasierDifficulties()
{
if (editedAITrigger == null)
return;

var messageBox = EditorMessageBox.Show(WindowManager,
"Are you sure?",
"Cloning this AI trigger for easier difficulties will create duplicate instances" + Environment.NewLine +
"of this AI trigger for Medium and Easy difficulties, setting the difficulty" + Environment.NewLine +
"setting for each AI trigger to Medium and Easy, respectively." + Environment.NewLine +
"This will set the current AI trigger's difficulty to Hard only." + Environment.NewLine + Environment.NewLine +
"In case the AI trigger references a Primary or Secondary TeamTypes," + Environment.NewLine +
"those TeamTypes and their TaskForoces would be duplicated for easier difficulties." + Environment.NewLine +
"If those duplicates already exist, this action will set the AI triggers to use those " + Environment.NewLine +
"TeamTypes instead." + Environment.NewLine + Environment.NewLine +
"The script assumes that this AI Trigger has the words 'H' or 'Hard'" + Environment.NewLine +
"in their name and in their respective TeamTypes and TaskForces." + Environment.NewLine + Environment.NewLine +
"No un-do is available. Do you want to continue?", MessageBoxButtons.YesNo);

messageBox.YesClickedAction = _ => DoCloneForEasierDifficulties();
}

private void DoCloneForEasierDifficulties()
{
editedAITrigger.Hard = true;
editedAITrigger.Medium = false;
editedAITrigger.Easy = false;

var mediumAITrigger = editedAITrigger.Clone(map.GetNewUniqueInternalId());
mediumAITrigger.Hard = false;
mediumAITrigger.Medium = true;

var easyAITrigger = editedAITrigger.Clone(map.GetNewUniqueInternalId());
easyAITrigger.Hard = false;
easyAITrigger.Easy = true;

mediumAITrigger.Name = Helpers.ConvertNameToNewDifficulty(editedAITrigger.Name, Difficulty.Hard, Difficulty.Medium);
easyAITrigger.Name = Helpers.ConvertNameToNewDifficulty(editedAITrigger.Name, Difficulty.Hard, Difficulty.Easy);

map.AITriggerTypes.Add(mediumAITrigger);
map.AITriggerTypes.Add(easyAITrigger);

CloneTeamTypesAndAttachToAITrigger(mediumAITrigger, Difficulty.Medium, true);
CloneTeamTypesAndAttachToAITrigger(mediumAITrigger, Difficulty.Medium, false);
CloneTeamTypesAndAttachToAITrigger(easyAITrigger, Difficulty.Easy, true);
CloneTeamTypesAndAttachToAITrigger(easyAITrigger, Difficulty.Easy, false);

ListAITriggers();
}

private void CloneTeamTypesAndAttachToAITrigger(AITriggerType newAITrigger, Difficulty difficulty, bool isPrimaryTeamType)
{
var teamTypeToClone = isPrimaryTeamType ? editedAITrigger.PrimaryTeam : editedAITrigger.SecondaryTeam;

if (teamTypeToClone == null)
return;

// Check if its lower difficulty counterpart already exists, if it doesn't, create it
string newDifficultyName = Helpers.ConvertNameToNewDifficulty(teamTypeToClone.Name, Difficulty.Hard, difficulty);

var newDifficultyTeamType = map.TeamTypes.Find(teamType => teamType.Name == newDifficultyName);

if (newDifficultyTeamType == null)
{
// clone the teams type and give it a new name
newDifficultyTeamType = teamTypeToClone.Clone(map.GetNewUniqueInternalId());
newDifficultyTeamType.Name = newDifficultyName;

map.AddTeamType(newDifficultyTeamType);

// If the team type has a task force, check if it has lower difficulty duplicate; if not, create it
if (teamTypeToClone.TaskForce != null)
{
var taskForceToClone = teamTypeToClone.TaskForce;

newDifficultyName = Helpers.ConvertNameToNewDifficulty(taskForceToClone.Name, Difficulty.Hard, difficulty);

var newDifficultyTaskForce = map.TaskForces.Find(taskForce => taskForce.Name == newDifficultyName);

if (newDifficultyTaskForce == null)
{
newDifficultyTaskForce = taskForceToClone.Clone(map.GetNewUniqueInternalId());
newDifficultyTaskForce.Name = newDifficultyName;

map.AddTaskForce(newDifficultyTaskForce);
}

newDifficultyTeamType.TaskForce = newDifficultyTaskForce;
}
}

// Regardless: assign to relevant team to the new AI trigger
if (isPrimaryTeamType)
{
newAITrigger.PrimaryTeam = newDifficultyTeamType;
}
else
{
newAITrigger.SecondaryTeam = newDifficultyTeamType;
}
}

private void DdActions_SelectedIndexChanged(object sender, EventArgs e)
{
var item = ddActions.SelectedItem;
if (item == null)
return;

if (item.Tag == null)
return;

if (item.Tag is Action action)
action();

ddActions.SelectedIndexChanged -= DdActions_SelectedIndexChanged;
ddActions.SelectedIndex = 0;
ddActions.SelectedIndexChanged += DdActions_SelectedIndexChanged;
}

private void BtnOpenPrimaryTeam_LeftClick(object sender, EventArgs e)
{
if (editedAITrigger == null || editedAITrigger.PrimaryTeam == null)
Expand Down
Loading