Skip to content

Commit eb4ecb1

Browse files
authored
Add warning for triggers using Building Exists incorrectly
1 parent 621f618 commit eb4ecb1

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

src/TSMapEditor/Config/Translations/en/Translation_en.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ Map.CheckForIssues.SpecialWaypointUsed=The map makes use of waypoint #{0}. In Ti
142142
Map.CheckForAITriggerTeamWithMaxZeroIssue.TeamTypeMax=Team '{0}', linked to AITrigger '{1}', has Max=0. This prevents the AI from building the team.
143143
Map.CheckForIssues.MismatchedDifficultyForEnableTrigger=The trigger "{0}" has "{1}" as its difficulty level, but it enables a trigger "{2}" which has "{3}" as its difficulty.
144144
Map.CheckForIssues.MismatchedDifficultyForDisableTrigger=The trigger "{0}" has "{1}" as its difficulty level, but it disables a trigger "{2}" which has "{3}" as its difficulty.
145+
Map.CheckForIssues.BuildingExists.InvalidBuildingType=Could not find buildingType with index {0} as was specified in trigger '{1}'
146+
Map.CheckForIssues.BuildingExists.InvalidTriggerSetup=Trigger '{0}' has a Building Exists event for building {1} ({2}), but trigger house '{3}' has neither a preplaced structure, a base node for it, or a unit that deploys into it.@Did you forget to set the correct house or add the unit into a TeamType for the house?
147+
145148
146149
; *************************************************
147150
; Difficulty

src/TSMapEditor/Misc/MapIssueChecker.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Rampastring.Tools;
22
using System;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using TSMapEditor.CCEngine;
56
using TSMapEditor.Models;
67
using TSMapEditor.Models.Enums;
@@ -12,6 +13,7 @@ public static class MapIssueChecker
1213
{
1314
private const int EnableTriggerActionIndex = 53;
1415
private const int DisableTriggerActionIndex = 54;
16+
private const int BuildingExistsTriggerEventIndex = 32;
1517
private const int TriggerParamIndex = 1;
1618

1719
/// <summary>
@@ -388,6 +390,91 @@ public static List<string> CheckForIssues(Map map)
388390
trigger.Name, trigger.HouseType));
389391
}
390392

393+
// Check for triggers in SP that have Building Exists event but house belongs to an AI
394+
// that doesn't ever build or deploy a unit into the building
395+
if (!map.IsLikelyMultiplayer())
396+
{
397+
foreach (var trigger in map.Triggers)
398+
{
399+
// Get the house of the trigger
400+
var house = map.Houses.Find(house => house.ININame == trigger.HouseType);
401+
402+
if (house == null)
403+
continue; // will be reported by the check for invalid owners
404+
405+
// This check only checks AI houses as they're controlled by mappers in SP missions
406+
if (house.PlayerControl)
407+
continue;
408+
409+
foreach (var condition in trigger.Conditions)
410+
{
411+
// Check if current condition is Building Exists condition
412+
if (condition.ConditionIndex != BuildingExistsTriggerEventIndex)
413+
continue;
414+
415+
// Get the condition's building index
416+
int buildingIndex = int.Parse(condition.Parameters[1]);
417+
418+
// Try to find a pre-placed structure on the map with the index belonging to the trigger's house
419+
// If found - all good, house has this structure and trigger is valid
420+
if (map.Structures.Exists(structure => structure.ObjectType.Index == buildingIndex && structure.Owner == house))
421+
continue;
422+
423+
if (buildingIndex < 0 || buildingIndex >= map.Rules.BuildingTypes.Count)
424+
{
425+
issueList.Add(string.Format(Translate(map, "CheckForIssues.BuildingExists.InvalidBuildingType",
426+
"No building type index {0} exists as was specified in trigger '{1}'"),
427+
buildingIndex, trigger.Name));
428+
continue;
429+
}
430+
431+
var buildingType = map.Rules.BuildingTypes[buildingIndex];
432+
433+
// Check the house's base nodes to see if the AI is intended to build it at some point
434+
// If found - all good, house will build this when it can (we assume they have a ConYard etc.)
435+
if (house.BaseNodes.Exists(baseNode => baseNode.StructureTypeName == buildingType.ININame))
436+
continue;
437+
438+
// Check if there is some techno that can deploy into this structure
439+
// If so, check if it's pre-placed or is in a task force in the TeamType used by the house
440+
var unitsThatDeployToBuilding = map.Rules.UnitTypes
441+
.FindAll(unitType => unitType.DeploysInto == buildingType.ININame)
442+
.ToList();
443+
444+
if (unitsThatDeployToBuilding.Count > 0)
445+
{
446+
if (map.Units.Exists(u => u.Owner == house && unitsThatDeployToBuilding.Contains(u.UnitType)))
447+
continue;
448+
449+
if (map.TeamTypes.Exists(teamType =>
450+
{
451+
if (teamType.HouseType != house.HouseType)
452+
return false;
453+
454+
if (teamType.TaskForce == null)
455+
return false;
456+
457+
return Array.Exists(teamType.TaskForce.TechnoTypes, tte =>
458+
tte != null &&
459+
tte.TechnoType.WhatAmI() == RTTIType.UnitType &&
460+
unitsThatDeployToBuilding.Contains((UnitType)tte.TechnoType));
461+
}))
462+
{
463+
continue;
464+
}
465+
}
466+
467+
// If we got here, then there is no preplaced structure or base node for this house, and no unit that can deploy into it either.
468+
// This means the trigger will never spring.
469+
issueList.Add(string.Format(Translate(map, "CheckForIssues.BuildingExists.InvalidTriggerSetup",
470+
"Trigger '{0}' has a Building Exists event for building {1} ({2}), but trigger house '{3}' has neither a preplaced structure, a base node for it, or a unit that deploys into it. " +
471+
Environment.NewLine +
472+
"Did you forget to set the correct house or add the unit into a TeamType for the house?"),
473+
trigger.Name, buildingIndex, buildingType.Name, house.ININame));
474+
}
475+
}
476+
}
477+
391478
// Check for triggers having too many actions. This can cause a crash because the game's buffer for parsing trigger actions
392479
// is limited (to 512 chars according to ModEnc)
393480
if (Constants.WarnOfTooManyTriggerActions)

src/TSMapEditor/Models/UnitType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public UnitType(string iniName) : base(iniName)
2222
public bool Turret { get; set; }
2323
public string SpeedType { get; set; }
2424
public string MovementZone { get; set; }
25+
public string DeploysInto { get; set; }
2526

2627
public int GetTurretStartFrame()
2728
{

0 commit comments

Comments
 (0)