Make Conquest- and StrategicVictoryConditions use objectives backend
Note: 3rd party KotH maps will need to be modified to work correctly with this change. Previously, StrategicVictoryConditions was a supplement to ConquestVictoryConditions. After this change, each works by itself. So KotH maps will need to remove the ConquestVictoryConditions trait from the player definitions, or both victory conditions will have to be satisfied to win the game.
This commit is contained in:
@@ -13,80 +13,79 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ConquestVictoryConditionsInfo : ITraitInfo
|
||||
public class ConquestVictoryConditionsInfo : ITraitInfo, Requires<MissionObjectivesInfo>
|
||||
{
|
||||
[Desc("Milliseconds")]
|
||||
[Desc("Delay for the end game notification in milliseconds.")]
|
||||
public int NotificationDelay = 1500;
|
||||
|
||||
public object Create(ActorInitializer init) { return new ConquestVictoryConditions(init.world, this); }
|
||||
public object Create(ActorInitializer init) { return new ConquestVictoryConditions(init.self, this); }
|
||||
}
|
||||
|
||||
public class ConquestVictoryConditions : ITick, IResolveOrder
|
||||
public class ConquestVictoryConditions : ITick, IResolveOrder, INotifyObjectivesUpdated
|
||||
{
|
||||
ConquestVictoryConditionsInfo Info;
|
||||
public ConquestVictoryConditions(World world, ConquestVictoryConditionsInfo info)
|
||||
readonly ConquestVictoryConditionsInfo info;
|
||||
readonly MissionObjectives mo;
|
||||
int objectiveID = -1;
|
||||
|
||||
public ConquestVictoryConditions(Actor self, ConquestVictoryConditionsInfo cvcInfo)
|
||||
{
|
||||
world.ObserveAfterWinOrLose = true;
|
||||
Info = info;
|
||||
info = cvcInfo;
|
||||
mo = self.Trait<MissionObjectives>();
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (self.Owner.WinState != WinState.Undefined || self.Owner.NonCombatant) return;
|
||||
|
||||
var hasAnything = self.World.ActorsWithTrait<MustBeDestroyed>()
|
||||
.Any(a => a.Actor.Owner == self.Owner);
|
||||
if (objectiveID < 0)
|
||||
objectiveID = mo.Add(self.Owner, "Destroy all opposition!");
|
||||
|
||||
if (!hasAnything && !self.Owner.NonCombatant)
|
||||
Lose(self);
|
||||
if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits())
|
||||
mo.MarkFailed(self.Owner, objectiveID);
|
||||
|
||||
var others = self.World.Players.Where(p => !p.NonCombatant
|
||||
&& p != self.Owner && p.Stances[self.Owner] != Stance.Ally);
|
||||
&& !p.IsAlliedWith(self.Owner));
|
||||
|
||||
if (!others.Any()) return;
|
||||
|
||||
if (others.All(p => p.WinState == WinState.Lost))
|
||||
Win(self);
|
||||
mo.MarkCompleted(self.Owner, objectiveID);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Surrender")
|
||||
Lose(self);
|
||||
mo.MarkFailed(self.Owner, objectiveID);
|
||||
}
|
||||
|
||||
public void Lose(Actor self)
|
||||
public void OnPlayerLost(Player player)
|
||||
{
|
||||
if (self.Owner.WinState == WinState.Lost) return;
|
||||
self.Owner.WinState = WinState.Lost;
|
||||
self.World.OnPlayerWinStateChanged(self.Owner);
|
||||
Game.Debug("{0} is defeated.".F(player.PlayerName));
|
||||
|
||||
Game.Debug("{0} is defeated.".F(self.Owner.PlayerName));
|
||||
|
||||
foreach (var a in self.World.Actors.Where(a => a.Owner == self.Owner))
|
||||
foreach (var a in player.World.Actors.Where(a => a.Owner == player))
|
||||
a.Kill(a);
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
if (player == player.World.LocalPlayer)
|
||||
{
|
||||
Game.RunAfterDelay(Info.NotificationDelay, () =>
|
||||
Game.RunAfterDelay(info.NotificationDelay, () =>
|
||||
{
|
||||
if (Game.IsCurrentWorld(self.World))
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", "Lose", self.Owner.Country.Race);
|
||||
if (Game.IsCurrentWorld(player.World))
|
||||
Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Lose", player.Country.Race);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void Win(Actor self)
|
||||
public void OnPlayerWon(Player player)
|
||||
{
|
||||
if (self.Owner.WinState == WinState.Won) return;
|
||||
self.Owner.WinState = WinState.Won;
|
||||
self.World.OnPlayerWinStateChanged(self.Owner);
|
||||
Game.Debug("{0} is victorious.".F(player.PlayerName));
|
||||
|
||||
Game.Debug("{0} is victorious.".F(self.Owner.PlayerName));
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
Game.RunAfterDelay(Info.NotificationDelay, () => Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", "Win", self.Owner.Country.Race));
|
||||
if (player == player.World.LocalPlayer)
|
||||
Game.RunAfterDelay(info.NotificationDelay, () => Sound.PlayNotification(player.World.Map.Rules, player, "Speech", "Win", player.Country.Race));
|
||||
}
|
||||
|
||||
public void OnObjectiveAdded(Player player, int id) {}
|
||||
public void OnObjectiveCompleted(Player player, int id) {}
|
||||
public void OnObjectiveFailed(Player player, int id) {}
|
||||
}
|
||||
|
||||
[Desc("Tag trait for things that must be destroyed for a short game to end.")]
|
||||
|
||||
Reference in New Issue
Block a user