@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA
|
||||
public void UnitProducedByOther(Actor self, Actor producer, Actor produced)
|
||||
{
|
||||
// No recursive cloning!
|
||||
if (producer.HasTrait<ClonesProducedUnits>())
|
||||
if (producer.Owner != self.Owner || producer.HasTrait<ClonesProducedUnits>())
|
||||
return;
|
||||
|
||||
var ci = produced.Info.Traits.GetOrDefault<CloneableInfo>();
|
||||
|
||||
@@ -544,6 +544,8 @@
|
||||
<Compile Include="Warheads\GrantUpgradeWarhead.cs" />
|
||||
<Compile Include="Crates\GrantUpgradeCrateAction.cs" />
|
||||
<Compile Include="Scripting\Properties\UpgradeProperties.cs" />
|
||||
<Compile Include="UpgradeActorsNear.cs" />
|
||||
<Compile Include="WithRangeCircle.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">
|
||||
|
||||
@@ -98,9 +98,7 @@ namespace OpenRA.Mods.RA
|
||||
foreach (var t in self.TraitsImplementing<INotifyProduction>())
|
||||
t.UnitProduced(self, newUnit, exit);
|
||||
|
||||
var notifyOthers = self.World.ActorsWithTrait<INotifyOtherProduction>()
|
||||
.Where(a => a.Actor.Owner == self.Owner);
|
||||
|
||||
var notifyOthers = self.World.ActorsWithTrait<INotifyOtherProduction>();
|
||||
foreach (var notify in notifyOthers)
|
||||
notify.Trait.UnitProducedByOther(notify.Actor, self, newUnit);
|
||||
|
||||
|
||||
133
OpenRA.Mods.RA/UpgradeActorsNear.cs
Normal file
133
OpenRA.Mods.RA/UpgradeActorsNear.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Applies an upgrade to actors within a specified range.")]
|
||||
public class UpgradeActorsNearInfo : ITraitInfo
|
||||
{
|
||||
[Desc("The upgrades to grant.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
[Desc("The range to search for actors to upgrade.")]
|
||||
public readonly WRange Range = WRange.FromCells(3);
|
||||
|
||||
[Desc("What diplomatic stances are affected.")]
|
||||
public readonly Stance ValidStances = Stance.Ally;
|
||||
|
||||
[Desc("Grant the upgrades apply to this actor.")]
|
||||
public readonly bool AffectsParent = false;
|
||||
|
||||
public readonly string EnableSound = null;
|
||||
public readonly string DisableSound = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new UpgradeActorsNear(init.self, this); }
|
||||
}
|
||||
|
||||
public class UpgradeActorsNear : ITick, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyOtherProduction
|
||||
{
|
||||
readonly UpgradeActorsNearInfo info;
|
||||
readonly Actor self;
|
||||
|
||||
int proximityTrigger;
|
||||
WPos cachedPosition;
|
||||
WRange cachedRange;
|
||||
WRange desiredRange;
|
||||
|
||||
bool cachedDisabled = true;
|
||||
|
||||
public UpgradeActorsNear(Actor self, UpgradeActorsNearInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.self = self;
|
||||
cachedRange = info.Range;
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
cachedPosition = self.CenterPosition;
|
||||
proximityTrigger = self.World.ActorMap.AddProximityTrigger(cachedPosition, cachedRange, ActorEntered, ActorExited);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveProximityTrigger(proximityTrigger);
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
var disabled = self.IsDisabled();
|
||||
|
||||
if (cachedDisabled != disabled)
|
||||
{
|
||||
Sound.Play(disabled ? info.DisableSound : info.EnableSound, self.CenterPosition);
|
||||
desiredRange = disabled ? WRange.Zero : info.Range;
|
||||
cachedDisabled = disabled;
|
||||
}
|
||||
|
||||
if (self.CenterPosition != cachedPosition || desiredRange != cachedRange)
|
||||
{
|
||||
cachedPosition = self.CenterPosition;
|
||||
cachedRange = desiredRange;
|
||||
self.World.ActorMap.UpdateProximityTrigger(proximityTrigger, cachedPosition, cachedRange);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorEntered(Actor a)
|
||||
{
|
||||
if (a.Destroyed)
|
||||
return;
|
||||
|
||||
if (a == self && !info.AffectsParent)
|
||||
return;
|
||||
|
||||
var stance = self.Owner.Stances[a.Owner];
|
||||
if (!info.ValidStances.HasFlag(stance))
|
||||
return;
|
||||
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
if (um != null)
|
||||
foreach (var u in info.Upgrades)
|
||||
um.GrantUpgrade(a, u, this);
|
||||
}
|
||||
|
||||
public void UnitProducedByOther(Actor self, Actor producer, Actor produced)
|
||||
{
|
||||
// Work around for actors produced within the region not triggering until the second tick
|
||||
if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= info.Range.Range * info.Range.Range)
|
||||
{
|
||||
var stance = self.Owner.Stances[produced.Owner];
|
||||
if (!info.ValidStances.HasFlag(stance))
|
||||
return;
|
||||
|
||||
var um = produced.TraitOrDefault<UpgradeManager>();
|
||||
if (um != null)
|
||||
foreach (var u in info.Upgrades)
|
||||
um.GrantTimedUpgrade(produced, u, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorExited(Actor a)
|
||||
{
|
||||
if (a == self || a.Destroyed)
|
||||
return;
|
||||
|
||||
var um = a.TraitOrDefault<UpgradeManager>();
|
||||
if (um != null)
|
||||
foreach (var u in info.Upgrades)
|
||||
um.RevokeUpgrade(a, u, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
76
OpenRA.Mods.RA/WithRangeCircle.cs
Normal file
76
OpenRA.Mods.RA/WithRangeCircle.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Renders an arbitrary circle when selected or placing a structure")]
|
||||
class WithRangeCircleInfo : ITraitInfo, IPlaceBuildingDecoration
|
||||
{
|
||||
[Desc("Type of range circle. used to decide which circles to draw on other structures during building placement.")]
|
||||
public readonly string Type = null;
|
||||
|
||||
[Desc("Color of the circle")]
|
||||
public readonly Color Color = Color.FromArgb(128, Color.White);
|
||||
|
||||
[Desc("Range of the circle")]
|
||||
public readonly WRange Range = WRange.Zero;
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
|
||||
{
|
||||
yield return new RangeCircleRenderable(
|
||||
centerPosition,
|
||||
Range,
|
||||
0,
|
||||
Color,
|
||||
Color.FromArgb(96, Color.Black)
|
||||
);
|
||||
|
||||
foreach (var a in w.ActorsWithTrait<WithRangeCircle>())
|
||||
if (a.Actor.Owner == a.Actor.World.LocalPlayer && a.Trait.Info.Type == Type)
|
||||
foreach (var r in a.Trait.RenderAfterWorld(wr))
|
||||
yield return r;
|
||||
}
|
||||
|
||||
public object Create(ActorInitializer init) { return new WithRangeCircle(init.self, this); }
|
||||
}
|
||||
|
||||
class WithRangeCircle : IPostRenderSelection
|
||||
{
|
||||
public readonly WithRangeCircleInfo Info;
|
||||
readonly Actor self;
|
||||
|
||||
public WithRangeCircle(Actor self, WithRangeCircleInfo info)
|
||||
{
|
||||
this.self = self;
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr)
|
||||
{
|
||||
if (self.Owner != self.World.LocalPlayer)
|
||||
yield break;
|
||||
|
||||
yield return new RangeCircleRenderable(
|
||||
self.CenterPosition,
|
||||
Info.Range,
|
||||
0,
|
||||
Info.Color,
|
||||
Color.FromArgb(96, Color.Black)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user