Merge pull request #3063 from pchote/repairable-bridges

Repairable bridges, closes #2619
This commit is contained in:
Matthias Mailänder
2013-04-15 05:49:56 -07:00
41 changed files with 704 additions and 200 deletions

View File

@@ -54,9 +54,12 @@ namespace OpenRA.Orders
.OrderByDescending(a => a.SelectionPriority())
.FirstOrDefault();
if (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any())
if (underCursor != null && underCursor.HasTrait<Selectable>())
if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any()))
{
var selectable = underCursor.TraitOrDefault<Selectable>();
if (selectable != null && selectable.Info.Selectable)
useSelect = true;
}
var orders = world.Selection.Actors
.Select(a => OrderForUnit(a, xy, mi, underCursor))

View File

@@ -69,6 +69,35 @@ namespace OpenRA.Traits
}
}
public void Resurrect(Actor self, Actor repairer)
{
if (!IsDead)
return;
hp = MaxHP;
var ai = new AttackInfo
{
Attacker = repairer,
Damage = -MaxHP,
DamageState = this.DamageState,
PreviousDamageState = DamageState.Dead,
Warhead = null,
};
foreach (var nd in self.TraitsImplementing<INotifyDamage>()
.Concat(self.Owner.PlayerActor.TraitsImplementing<INotifyDamage>()))
nd.Damaged(self, ai);
foreach (var nd in self.TraitsImplementing<INotifyDamageStateChanged>())
nd.DamageStateChanged(self, ai);
if (repairer != null && repairer.IsInWorld && !repairer.IsDead())
foreach (var nd in repairer.TraitsImplementing<INotifyAppliedDamage>()
.Concat(repairer.Owner.PlayerActor.TraitsImplementing<INotifyAppliedDamage>()))
nd.AppliedDamage(repairer, self, ai);
}
public void InflictDamage(Actor self, Actor attacker, int damage, WarheadInfo warhead, bool ignoreModifiers)
{
if (IsDead) return; /* overkill! don't count extra hits as more kills! */

View File

@@ -16,21 +16,30 @@ namespace OpenRA.Traits
{
public class SelectableInfo : ITraitInfo
{
public readonly bool Selectable = true;
public readonly int Priority = 10;
public readonly int[] Bounds = null;
[VoiceReference] public readonly string Voice = null;
public object Create(ActorInitializer init) { return new Selectable(init.self); }
public object Create(ActorInitializer init) { return new Selectable(init.self, this); }
}
public class Selectable : IPostRenderSelection
{
public SelectableInfo Info;
Actor self;
public Selectable(Actor self) { this.self = self; }
public Selectable(Actor self, SelectableInfo info)
{
this.self = self;
Info = info;
}
public void RenderAfterWorld(WorldRenderer wr)
{
if (!Info.Selectable)
return;
var bounds = self.Bounds.Value;
var xy = new float2(bounds.Left, bounds.Top);
@@ -44,6 +53,9 @@ namespace OpenRA.Traits
public void DrawRollover(WorldRenderer wr, Actor self)
{
if (!Info.Selectable)
return;
var bounds = self.Bounds.Value;
var xy = new float2(bounds.Left, bounds.Top);

View File

@@ -184,7 +184,7 @@ namespace OpenRA.Widgets
IEnumerable<Actor> SelectActorsInBox(World world, PPos a, PPos b, Func<Actor, bool> cond)
{
return world.FindUnits(a, b)
.Where(x => x.HasTrait<Selectable>() && !world.FogObscures(x) && cond(x))
.Where(x => x.HasTrait<Selectable>() && x.Trait<Selectable>().Info.Selectable && !world.FogObscures(x) && cond(x))
.GroupBy(x => x.GetSelectionPriority())
.OrderByDescending(g => g.Key)
.Select(g => g.AsEnumerable())