206 lines
8.1 KiB
C#
206 lines
8.1 KiB
C#
#nullable enable
|
|
using Microsoft.Xna.Framework;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
public enum FactionAffiliation
|
|
{
|
|
Positive,
|
|
Neutral,
|
|
Negative
|
|
}
|
|
|
|
class Faction
|
|
{
|
|
public Reputation Reputation { get; }
|
|
public FactionPrefab Prefab { get; }
|
|
|
|
public Faction(CampaignMetadata? metadata, FactionPrefab prefab)
|
|
{
|
|
Prefab = prefab;
|
|
Reputation = new Reputation(metadata, this, prefab.MinReputation, prefab.MaxReputation, prefab.InitialReputation);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get what kind of affiliation this faction has towards the player depending on who they chose to side with via talents
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static FactionAffiliation GetPlayerAffiliationStatus(Faction faction)
|
|
{
|
|
if (GameMain.GameSession?.Campaign?.Factions is not { } factions) { return FactionAffiliation.Neutral; }
|
|
|
|
bool isHighest = true;
|
|
foreach (Faction otherFaction in factions)
|
|
{
|
|
if (otherFaction == faction || otherFaction.Reputation.Value < faction.Reputation.Value) { continue; }
|
|
|
|
isHighest = false;
|
|
break;
|
|
}
|
|
|
|
return isHighest ? FactionAffiliation.Positive : FactionAffiliation.Negative;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{base.ToString()} ({Prefab?.Identifier.ToString() ?? "null"})";
|
|
}
|
|
}
|
|
|
|
internal class FactionPrefab : Prefab
|
|
{
|
|
public readonly static PrefabCollection<FactionPrefab> Prefabs = new PrefabCollection<FactionPrefab>();
|
|
|
|
public LocalizedString Name { get; }
|
|
|
|
public LocalizedString Description { get; }
|
|
public LocalizedString ShortDescription { get; }
|
|
|
|
public Identifier OpposingFaction { get; }
|
|
|
|
public class HireableCharacter
|
|
{
|
|
public readonly Identifier NPCSetIdentifier;
|
|
public readonly Identifier NPCIdentifier;
|
|
public readonly float MinReputation;
|
|
|
|
public HireableCharacter(ContentXElement element)
|
|
{
|
|
NPCSetIdentifier = element.GetAttributeIdentifier("from", element.GetAttributeIdentifier("npcsetidentifier", Identifier.Empty));
|
|
NPCIdentifier = element.GetAttributeIdentifier("identifier", element.GetAttributeIdentifier("npcidentifier", Identifier.Empty));
|
|
MinReputation = element.GetAttributeFloat("minreputation", 0.0f);
|
|
}
|
|
}
|
|
|
|
public ImmutableArray<HireableCharacter> HireableCharacters;
|
|
|
|
public class AutomaticMission
|
|
{
|
|
public readonly Identifier MissionTag;
|
|
public readonly LevelData.LevelType LevelType;
|
|
public readonly float MinReputation, MaxReputation;
|
|
public readonly float MinProbability, MaxProbability;
|
|
public readonly int MaxDistanceFromFactionOutpost;
|
|
public readonly bool DisallowBetweenOtherFactionOutposts;
|
|
|
|
public AutomaticMission(ContentXElement element, string parentDebugName)
|
|
{
|
|
MissionTag = element.GetAttributeIdentifier("missiontag", Identifier.Empty);
|
|
LevelType = element.GetAttributeEnum("leveltype", LevelData.LevelType.LocationConnection);
|
|
MinReputation = element.GetAttributeFloat("minreputation", 0.0f);
|
|
MaxReputation = element.GetAttributeFloat("maxreputation", 0.0f);
|
|
if (MinReputation > MaxReputation)
|
|
{
|
|
DebugConsole.ThrowError($"Error in faction prefab \"{parentDebugName}\": MinReputation cannot be larger than MaxReputation.");
|
|
}
|
|
float probability = element.GetAttributeFloat("probability", 0.0f);
|
|
MinProbability = element.GetAttributeFloat("minprobability", probability);
|
|
MaxProbability = element.GetAttributeFloat("maxprobability", probability);
|
|
MaxDistanceFromFactionOutpost = element.GetAttributeInt(nameof(MaxDistanceFromFactionOutpost), int.MaxValue);
|
|
DisallowBetweenOtherFactionOutposts = element.GetAttributeBool(nameof(DisallowBetweenOtherFactionOutposts), false);
|
|
}
|
|
}
|
|
|
|
public ImmutableArray<AutomaticMission> AutomaticMissions;
|
|
|
|
public bool StartOutpost { get; }
|
|
|
|
|
|
public int MenuOrder { get; }
|
|
|
|
/// <summary>
|
|
/// How low the reputation can drop on this faction
|
|
/// </summary>
|
|
public int MinReputation { get; }
|
|
|
|
/// <summary>
|
|
/// Maximum reputation level you can gain on this faction
|
|
/// </summary>
|
|
public int MaxReputation { get; }
|
|
|
|
/// <summary>
|
|
/// What reputation does this faction start with
|
|
/// </summary>
|
|
public int InitialReputation { get; }
|
|
|
|
public float ControlledOutpostPercentage { get; }
|
|
|
|
public float SecondaryControlledOutpostPercentage { get; }
|
|
|
|
#if CLIENT
|
|
public Sprite? Icon { get; private set; }
|
|
|
|
public Sprite? IconSmall { get; private set; }
|
|
|
|
public Sprite? BackgroundPortrait { get; private set; }
|
|
#endif
|
|
|
|
public Color IconColor { get; }
|
|
|
|
public FactionPrefab(ContentXElement element, FactionsFile file) : base(file, element.GetAttributeIdentifier("identifier", string.Empty))
|
|
{
|
|
MenuOrder = element.GetAttributeInt("menuorder", 0);
|
|
StartOutpost = element.GetAttributeBool("startoutpost", false);
|
|
MinReputation = element.GetAttributeInt("minreputation", -100);
|
|
MaxReputation = element.GetAttributeInt("maxreputation", 100);
|
|
InitialReputation = element.GetAttributeInt("initialreputation", 0);
|
|
ControlledOutpostPercentage = element.GetAttributeFloat("controlledoutpostpercentage", 0);
|
|
SecondaryControlledOutpostPercentage = element.GetAttributeFloat("secondarycontrolledoutpostpercentage", 0);
|
|
Name = element.GetAttributeString("name", null) ?? TextManager.Get($"faction.{Identifier}").Fallback("Unnamed");
|
|
Description = element.GetAttributeString("description", null) ?? TextManager.Get($"faction.{Identifier}.description").Fallback("");
|
|
ShortDescription = element.GetAttributeString("shortdescription", null) ?? TextManager.Get($"faction.{Identifier}.shortdescription").Fallback("");
|
|
OpposingFaction = element.GetAttributeIdentifier(nameof(OpposingFaction), Identifier.Empty);
|
|
|
|
List<HireableCharacter> hireableCharacters = new List<HireableCharacter>();
|
|
List<AutomaticMission> automaticMissions = new List<AutomaticMission>();
|
|
foreach (var subElement in element.Elements())
|
|
{
|
|
var subElementId = subElement.NameAsIdentifier();
|
|
if (subElementId == "icon")
|
|
{
|
|
IconColor = subElement.GetAttributeColor("color", Color.White);
|
|
#if CLIENT
|
|
Icon = new Sprite(subElement);
|
|
#endif
|
|
}
|
|
else if (subElementId == "iconsmall")
|
|
{
|
|
#if CLIENT
|
|
IconSmall = new Sprite(subElement);
|
|
#endif
|
|
}
|
|
else if (subElementId == "portrait")
|
|
{
|
|
#if CLIENT
|
|
BackgroundPortrait = new Sprite(subElement);
|
|
#endif
|
|
}
|
|
else if (subElementId == "hireable")
|
|
{
|
|
hireableCharacters.Add(new HireableCharacter(subElement));
|
|
}
|
|
else if (subElementId == "mission" || subElementId == "automaticmission")
|
|
{
|
|
automaticMissions.Add(new AutomaticMission(subElement, Identifier.ToString()));
|
|
}
|
|
}
|
|
HireableCharacters = hireableCharacters.ToImmutableArray();
|
|
AutomaticMissions = automaticMissions.ToImmutableArray();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{base.ToString()} ({Identifier})";
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
#if CLIENT
|
|
Icon?.Remove();
|
|
Icon = null;
|
|
#endif
|
|
}
|
|
}
|
|
} |