Initial commit: OpenRA game engine
Fork from OpenRA/OpenRA with one-click launch script (start-ra.cmd) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
143
OpenRA.Mods.Common/Effects/Beacon.cs
Normal file
143
OpenRA.Mods.Common/Effects/Beacon.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Scripting;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class Beacon : IEffect, IScriptBindable, IEffectAboveShroud
|
||||
{
|
||||
const int MaxArrowHeight = 512;
|
||||
|
||||
readonly Player owner;
|
||||
readonly WPos position;
|
||||
readonly bool isPlayerPalette;
|
||||
readonly string beaconPalette, posterPalette;
|
||||
readonly Animation arrow, beacon, circles, clock, poster;
|
||||
readonly int duration;
|
||||
|
||||
int delay;
|
||||
int arrowHeight = MaxArrowHeight;
|
||||
int arrowSpeed = 50;
|
||||
int tick;
|
||||
|
||||
// Player-placed beacons are removed after a delay
|
||||
public Beacon(Player owner, WPos position, int duration, string beaconPalette, bool isPlayerPalette,
|
||||
string beaconCollection, string beaconSequence, string arrowSprite, string circleSprite, int delay = 0)
|
||||
{
|
||||
this.owner = owner;
|
||||
this.position = position;
|
||||
this.beaconPalette = beaconPalette;
|
||||
this.isPlayerPalette = isPlayerPalette;
|
||||
this.duration = duration;
|
||||
this.delay = delay;
|
||||
|
||||
if (!string.IsNullOrEmpty(beaconSequence))
|
||||
{
|
||||
beacon = new Animation(owner.World, beaconCollection);
|
||||
beacon.PlayRepeating(beaconSequence);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(arrowSprite))
|
||||
{
|
||||
arrow = new Animation(owner.World, beaconCollection);
|
||||
arrow.Play(arrowSprite);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(circleSprite))
|
||||
{
|
||||
circles = new Animation(owner.World, beaconCollection);
|
||||
circles.Play(circleSprite);
|
||||
}
|
||||
}
|
||||
|
||||
// By default, support power beacons are expected to clean themselves up
|
||||
public Beacon(Player owner, WPos position, bool isPlayerPalette, string palette, string posterCollection, string posterType, string posterPalette,
|
||||
string beaconSequence, string arrowSequence, string circleSequence, string clockSequence, Func<float> clockFraction, int delay = 0, int duration = -1)
|
||||
: this(owner, position, duration, palette, isPlayerPalette, posterCollection, beaconSequence, arrowSequence, circleSequence, delay)
|
||||
{
|
||||
this.posterPalette = posterPalette;
|
||||
|
||||
if (posterType != null)
|
||||
{
|
||||
poster = new Animation(owner.World, posterCollection);
|
||||
poster.Play(posterType);
|
||||
|
||||
if (clockFraction != null)
|
||||
{
|
||||
clock = new Animation(owner.World, posterCollection);
|
||||
clock.PlayFetchIndex(clockSequence, () => ((int)(clockFraction() * (clock.CurrentSequence.Length - 1))).Clamp(0, clock.CurrentSequence.Length - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IEffect.Tick(World world)
|
||||
{
|
||||
if (delay-- > 0)
|
||||
return;
|
||||
|
||||
arrowHeight += arrowSpeed;
|
||||
var clamped = arrowHeight.Clamp(0, MaxArrowHeight);
|
||||
if (arrowHeight != clamped)
|
||||
{
|
||||
arrowHeight = clamped;
|
||||
arrowSpeed *= -1;
|
||||
}
|
||||
|
||||
arrow?.Tick();
|
||||
beacon?.Tick();
|
||||
circles?.Tick();
|
||||
clock?.Tick();
|
||||
|
||||
if (duration > 0 && duration <= tick++)
|
||||
owner.World.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IEffect.Render(WorldRenderer r) { return SpriteRenderable.None; }
|
||||
|
||||
IEnumerable<IRenderable> IEffectAboveShroud.RenderAboveShroud(WorldRenderer r)
|
||||
{
|
||||
if (delay > 0)
|
||||
yield break;
|
||||
|
||||
if (!owner.IsAlliedWith(owner.World.RenderPlayer))
|
||||
yield break;
|
||||
|
||||
var palette = r.Palette(isPlayerPalette ? beaconPalette + owner.InternalName : beaconPalette);
|
||||
|
||||
if (beacon != null)
|
||||
foreach (var a in beacon.Render(position, palette))
|
||||
yield return a;
|
||||
|
||||
if (circles != null)
|
||||
foreach (var a in circles.Render(position, palette))
|
||||
yield return a;
|
||||
|
||||
if (arrow != null)
|
||||
foreach (var a in arrow.Render(position + new WVec(0, 0, arrowHeight), palette))
|
||||
yield return a;
|
||||
|
||||
if (poster != null)
|
||||
{
|
||||
foreach (var a in poster.Render(position, r.Palette(posterPalette)))
|
||||
yield return a;
|
||||
|
||||
if (clock != null)
|
||||
foreach (var a in clock.Render(position, r.Palette(posterPalette)))
|
||||
yield return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
OpenRA.Mods.Common/Effects/ContrailFader.cs
Normal file
44
OpenRA.Mods.Common/Effects/ContrailFader.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class ContrailFader : IEffect
|
||||
{
|
||||
readonly WPos pos;
|
||||
readonly ContrailRenderable trail;
|
||||
int ticks;
|
||||
|
||||
public ContrailFader(WPos pos, ContrailRenderable trail)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.trail = trail;
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (ticks++ == trail.Length)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
|
||||
trail.Update(pos);
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
yield return trail;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
OpenRA.Mods.Common/Effects/FlashTarget.cs
Normal file
82
OpenRA.Mods.Common/Effects/FlashTarget.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class FlashTarget : IEffect
|
||||
{
|
||||
readonly Actor target;
|
||||
readonly int count;
|
||||
readonly int interval;
|
||||
|
||||
readonly TintModifiers modifiers;
|
||||
readonly float3 tint;
|
||||
readonly float? alpha;
|
||||
|
||||
int tick;
|
||||
|
||||
FlashTarget(Actor target, int count, int interval, int delay)
|
||||
{
|
||||
this.target = target;
|
||||
this.count = count;
|
||||
this.interval = interval;
|
||||
tick = -delay;
|
||||
|
||||
target.World.RemoveAll(effect => effect is FlashTarget flashTarget && flashTarget.target == target);
|
||||
}
|
||||
|
||||
public FlashTarget(Actor target, Color color, float alpha = 0.5f, int count = 2, int interval = 2, int delay = 0)
|
||||
: this(target, count, interval, delay)
|
||||
{
|
||||
modifiers = TintModifiers.ReplaceColor;
|
||||
tint = new float3(color.R, color.G, color.B) / 255f;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
public FlashTarget(Actor target, float3 tint, int count = 2, int interval = 2, int delay = 0)
|
||||
: this(target, count, interval, delay)
|
||||
{
|
||||
this.tint = tint;
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (++tick >= count * interval || !target.IsInWorld)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (target.IsInWorld && tick >= 0 && tick % interval == 0)
|
||||
{
|
||||
return target.Render(wr)
|
||||
.Where(r => !r.IsDecoration && r is IModifyableRenderable)
|
||||
.Select(r =>
|
||||
{
|
||||
var mr = (IModifyableRenderable)r;
|
||||
mr = mr.WithTint(tint, mr.TintModifiers | modifiers);
|
||||
if (alpha.HasValue)
|
||||
mr = mr.WithAlpha(alpha.Value);
|
||||
|
||||
return mr;
|
||||
});
|
||||
}
|
||||
|
||||
return SpriteRenderable.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
OpenRA.Mods.Common/Effects/FloatingSprite.cs
Normal file
95
OpenRA.Mods.Common/Effects/FloatingSprite.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public sealed class FloatingSprite : IEffect, ISpatiallyPartitionable
|
||||
{
|
||||
readonly ImmutableArray<WDist> speed;
|
||||
readonly ImmutableArray<WDist> gravity;
|
||||
readonly Animation anim;
|
||||
|
||||
readonly bool visibleThroughFog;
|
||||
readonly int turnRate;
|
||||
readonly int randomRate;
|
||||
readonly string palette;
|
||||
|
||||
WPos pos;
|
||||
WVec offset;
|
||||
int lifetime;
|
||||
int ticks;
|
||||
WAngle facing;
|
||||
|
||||
public FloatingSprite(Actor emitter, string image, ImmutableArray<string> sequences, string palette, bool isPlayerPalette,
|
||||
ImmutableArray<int> lifetime, ImmutableArray<WDist> speed, ImmutableArray<WDist> gravity, int turnRate, int randomRate, WPos pos, WAngle facing,
|
||||
bool visibleThroughFog = false)
|
||||
{
|
||||
var world = emitter.World;
|
||||
this.pos = pos;
|
||||
this.turnRate = turnRate;
|
||||
this.randomRate = randomRate;
|
||||
this.speed = speed;
|
||||
this.gravity = gravity;
|
||||
this.visibleThroughFog = visibleThroughFog;
|
||||
this.facing = facing;
|
||||
|
||||
anim = new Animation(world, image, () => facing);
|
||||
anim.PlayRepeating(sequences.Random(world.LocalRandom));
|
||||
world.ScreenMap.Add(this, pos, anim.Image);
|
||||
this.lifetime = Util.RandomInRange(world.LocalRandom, lifetime);
|
||||
|
||||
this.palette = isPlayerPalette ? palette + emitter.Owner.InternalName : palette;
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (--lifetime < 0)
|
||||
{
|
||||
world.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); });
|
||||
return;
|
||||
}
|
||||
|
||||
if (--ticks < 0)
|
||||
{
|
||||
var forward = Util.RandomDistance(world.LocalRandom, speed).Length;
|
||||
var height = Util.RandomDistance(world.LocalRandom, gravity).Length;
|
||||
|
||||
offset = new WVec(forward, 0, height);
|
||||
|
||||
if (turnRate > 0)
|
||||
facing = WAngle.FromFacing(Util.NormalizeFacing(facing.Facing + world.LocalRandom.Next(-turnRate, turnRate)));
|
||||
|
||||
offset = offset.Rotate(WRot.FromYaw(facing));
|
||||
|
||||
ticks = randomRate;
|
||||
}
|
||||
|
||||
anim.Tick();
|
||||
|
||||
pos += offset;
|
||||
|
||||
world.ScreenMap.Update(this, pos, anim.Image);
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (!visibleThroughFog && wr.World.FogObscures(pos))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
return anim.Render(pos, wr.Palette(palette));
|
||||
}
|
||||
}
|
||||
}
|
||||
63
OpenRA.Mods.Common/Effects/FloatingText.cs
Normal file
63
OpenRA.Mods.Common/Effects/FloatingText.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class FloatingText : IEffect, IEffectAnnotation
|
||||
{
|
||||
static readonly WVec Velocity = new(0, 0, 86);
|
||||
|
||||
readonly SpriteFont font;
|
||||
readonly string text;
|
||||
readonly Color color;
|
||||
int remaining;
|
||||
WPos pos;
|
||||
|
||||
public FloatingText(WPos pos, Color color, string text, int duration)
|
||||
{
|
||||
font = Game.Renderer.Fonts["TinyBold"];
|
||||
this.pos = pos;
|
||||
this.color = color;
|
||||
this.text = text;
|
||||
remaining = duration;
|
||||
}
|
||||
|
||||
void IEffect.Tick(World world)
|
||||
{
|
||||
if (--remaining <= 0)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
|
||||
pos += Velocity;
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IEffect.Render(WorldRenderer wr) { return SpriteRenderable.None; }
|
||||
|
||||
IEnumerable<IRenderable> IEffectAnnotation.RenderAnnotation(WorldRenderer wr)
|
||||
{
|
||||
if (wr.World.FogObscures(pos) || wr.World.ShroudObscures(pos))
|
||||
yield break;
|
||||
|
||||
yield return new TextAnnotationRenderable(font, pos, 0, color, text);
|
||||
}
|
||||
|
||||
public static string FormatCashTick(int cashAmount)
|
||||
{
|
||||
return $"{(cashAmount < 0 ? "-" : "+")}${Math.Abs(cashAmount)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
64
OpenRA.Mods.Common/Effects/MapNotificationEffect.cs
Normal file
64
OpenRA.Mods.Common/Effects/MapNotificationEffect.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class MapNotificationEffect : IEffect
|
||||
{
|
||||
readonly RadarPings radarPings;
|
||||
|
||||
readonly WPos pos;
|
||||
readonly Player player;
|
||||
readonly int duration;
|
||||
readonly string category;
|
||||
readonly string notification;
|
||||
readonly bool visible;
|
||||
readonly Color color;
|
||||
|
||||
int remainingDelay;
|
||||
|
||||
public MapNotificationEffect(Player player, string category, string notification, int delay,
|
||||
bool pingVisible, WPos pos, Color pingColor, int pingDuration = 50)
|
||||
{
|
||||
this.player = player;
|
||||
remainingDelay = delay;
|
||||
this.category = category;
|
||||
this.notification = notification;
|
||||
this.pos = pos;
|
||||
duration = pingDuration;
|
||||
visible = pingVisible;
|
||||
color = pingColor;
|
||||
|
||||
radarPings = player.World.WorldActor.TraitOrDefault<RadarPings>();
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (remainingDelay-- > 0)
|
||||
return;
|
||||
|
||||
Game.Sound.PlayNotification(player.World.Map.Rules, player, category, notification, player.Faction.InternalName);
|
||||
|
||||
if (visible && radarPings != null && player == player.World.RenderPlayer)
|
||||
radarPings.Add(() => true, pos, color, duration);
|
||||
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr) { return SpriteRenderable.None; }
|
||||
}
|
||||
}
|
||||
136
OpenRA.Mods.Common/Effects/RallyPointIndicator.cs
Normal file
136
OpenRA.Mods.Common/Effects/RallyPointIndicator.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class RallyPointIndicator : IEffect, IEffectAboveShroud, IEffectAnnotation
|
||||
{
|
||||
readonly Actor building;
|
||||
readonly RallyPoint rp;
|
||||
readonly Animation flag;
|
||||
readonly Animation circles;
|
||||
|
||||
readonly List<WPos> targetLineNodes = [];
|
||||
List<CPos> cachedLocations;
|
||||
|
||||
public RallyPointIndicator(Actor building, RallyPoint rp)
|
||||
{
|
||||
this.building = building;
|
||||
this.rp = rp;
|
||||
|
||||
if (rp.Info.Image != null)
|
||||
{
|
||||
if (rp.Info.FlagSequence != null)
|
||||
{
|
||||
flag = new Animation(building.World, rp.Info.Image);
|
||||
flag.PlayRepeating(rp.Info.FlagSequence);
|
||||
}
|
||||
|
||||
if (rp.Info.CirclesSequence != null)
|
||||
{
|
||||
circles = new Animation(building.World, rp.Info.Image);
|
||||
circles.Play(rp.Info.CirclesSequence);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTargetLineNodes(building.World);
|
||||
}
|
||||
|
||||
void IEffect.Tick(World world)
|
||||
{
|
||||
flag?.Tick();
|
||||
|
||||
circles?.Tick();
|
||||
|
||||
if (cachedLocations == null || !cachedLocations.SequenceEqual(rp.Path))
|
||||
{
|
||||
UpdateTargetLineNodes(world);
|
||||
|
||||
circles?.Play(rp.Info.CirclesSequence);
|
||||
}
|
||||
|
||||
if (!building.IsInWorld || building.IsDead)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
void UpdateTargetLineNodes(World world)
|
||||
{
|
||||
cachedLocations = rp.Path.ToList();
|
||||
targetLineNodes.Clear();
|
||||
foreach (var c in cachedLocations)
|
||||
targetLineNodes.Add(world.Map.CenterOfCell(c));
|
||||
|
||||
if (targetLineNodes.Count == 0)
|
||||
return;
|
||||
|
||||
var exit = building.NearestExitOrDefault(targetLineNodes[0]);
|
||||
targetLineNodes.Insert(0, building.CenterPosition + (exit?.Info.SpawnOffset ?? WVec.Zero));
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IEffect.Render(WorldRenderer wr) { return SpriteRenderable.None; }
|
||||
|
||||
IEnumerable<IRenderable> IEffectAboveShroud.RenderAboveShroud(WorldRenderer wr)
|
||||
{
|
||||
if (!building.IsInWorld || !building.Owner.IsAlliedWith(building.World.LocalPlayer))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
if (!building.World.Selection.Contains(building))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
var renderables = SpriteRenderable.None;
|
||||
if (targetLineNodes.Count > 0 && (circles != null || flag != null))
|
||||
{
|
||||
var palette = wr.Palette(rp.PaletteName);
|
||||
if (circles != null)
|
||||
renderables = renderables.Concat(circles.Render(targetLineNodes[^1], palette));
|
||||
|
||||
if (flag != null)
|
||||
renderables = renderables.Concat(flag.Render(targetLineNodes[^1], palette));
|
||||
}
|
||||
|
||||
return renderables;
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IEffectAnnotation.RenderAnnotation(WorldRenderer wr)
|
||||
{
|
||||
if (Game.Settings.Game.TargetLines == TargetLinesType.Disabled)
|
||||
return SpriteRenderable.None;
|
||||
|
||||
if (!building.IsInWorld || !building.Owner.IsAlliedWith(building.World.LocalPlayer))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
if (!building.World.Selection.Contains(building))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
if (targetLineNodes.Count == 0)
|
||||
return SpriteRenderable.None;
|
||||
|
||||
return RenderInner();
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> RenderInner()
|
||||
{
|
||||
var prev = targetLineNodes[0];
|
||||
foreach (var pos in targetLineNodes.Skip(1))
|
||||
{
|
||||
var targetLine = new[] { prev, pos };
|
||||
prev = pos;
|
||||
yield return new TargetLineRenderable(targetLine, building.OwnerColor(), rp.Info.LineWidth, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
OpenRA.Mods.Common/Effects/RevealShroudEffect.cs
Normal file
86
OpenRA.Mods.Common/Effects/RevealShroudEffect.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class RevealShroudEffect : IEffect
|
||||
{
|
||||
static readonly PPos[] NoCells = [];
|
||||
|
||||
readonly WPos pos;
|
||||
readonly Player player;
|
||||
readonly Shroud.SourceType sourceType;
|
||||
readonly WDist revealRadius;
|
||||
readonly PlayerRelationship validStances;
|
||||
readonly int duration;
|
||||
|
||||
int ticks;
|
||||
|
||||
public RevealShroudEffect(WPos pos, WDist radius, Shroud.SourceType type, Player forPlayer, PlayerRelationship stances, int delay = 0, int duration = 50)
|
||||
{
|
||||
this.pos = pos;
|
||||
player = forPlayer;
|
||||
revealRadius = radius;
|
||||
validStances = stances;
|
||||
sourceType = type;
|
||||
this.duration = duration;
|
||||
ticks = -delay;
|
||||
}
|
||||
|
||||
void AddCellsToPlayerShroud(Player p, PPos[] uv)
|
||||
{
|
||||
if (!validStances.HasRelationship(player.RelationshipWith(p)))
|
||||
return;
|
||||
|
||||
p.Shroud.AddSource(this, sourceType, uv);
|
||||
}
|
||||
|
||||
void RemoveCellsFromPlayerShroud(Player p) { p.Shroud.RemoveSource(this); }
|
||||
|
||||
PPos[] ProjectedCells(World world)
|
||||
{
|
||||
var map = world.Map;
|
||||
var range = revealRadius;
|
||||
if (range == WDist.Zero)
|
||||
return NoCells;
|
||||
|
||||
return Shroud.ProjectedCellsInRange(map, pos, WDist.Zero, range).ToArray();
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (ticks == 0)
|
||||
{
|
||||
var cells = ProjectedCells(world);
|
||||
foreach (var p in world.Players)
|
||||
AddCellsToPlayerShroud(p, cells);
|
||||
}
|
||||
|
||||
if (ticks == duration)
|
||||
{
|
||||
foreach (var p in world.Players)
|
||||
RemoveCellsFromPlayerShroud(p);
|
||||
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
ticks++;
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr) { return SpriteRenderable.None; }
|
||||
}
|
||||
}
|
||||
61
OpenRA.Mods.Common/Effects/SpawnActorEffect.cs
Normal file
61
OpenRA.Mods.Common/Effects/SpawnActorEffect.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class SpawnActorEffect : IEffect
|
||||
{
|
||||
readonly Actor actor;
|
||||
readonly CPos[] pathAfterSpawn;
|
||||
readonly Activity activityAtDestination;
|
||||
readonly IMove move;
|
||||
int remainingDelay;
|
||||
|
||||
public SpawnActorEffect(Actor actor)
|
||||
: this(actor, 0, [], null) { }
|
||||
|
||||
public SpawnActorEffect(Actor actor, int delay)
|
||||
: this(actor, delay, [], null) { }
|
||||
|
||||
public SpawnActorEffect(Actor actor, int delay, CPos[] pathAfterSpawn, Activity activityAtDestination)
|
||||
{
|
||||
this.actor = actor;
|
||||
remainingDelay = delay;
|
||||
this.pathAfterSpawn = pathAfterSpawn;
|
||||
this.activityAtDestination = activityAtDestination;
|
||||
move = actor.TraitOrDefault<IMove>();
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (remainingDelay-- > 0)
|
||||
return;
|
||||
|
||||
world.Add(actor);
|
||||
if (move != null)
|
||||
for (var j = 0; j < pathAfterSpawn.Length; j++)
|
||||
actor.QueueActivity(move.MoveTo(pathAfterSpawn[j], 2));
|
||||
|
||||
if (activityAtDestination != null)
|
||||
actor.QueueActivity(activityAtDestination);
|
||||
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr) { return SpriteRenderable.None; }
|
||||
}
|
||||
}
|
||||
47
OpenRA.Mods.Common/Effects/SpriteAnnotation.cs
Normal file
47
OpenRA.Mods.Common/Effects/SpriteAnnotation.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class SpriteAnnotation : IEffect, IEffectAnnotation
|
||||
{
|
||||
readonly string palette;
|
||||
readonly Animation anim;
|
||||
readonly WPos pos;
|
||||
|
||||
public SpriteAnnotation(WPos pos, World world, string image, string sequence, string palette)
|
||||
{
|
||||
this.palette = palette;
|
||||
this.pos = pos;
|
||||
anim = new Animation(world, image);
|
||||
anim.PlayThen(sequence, () => world.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); }));
|
||||
world.ScreenMap.Add(this, pos, anim.Image);
|
||||
}
|
||||
|
||||
void IEffect.Tick(World world)
|
||||
{
|
||||
anim.Tick();
|
||||
world.ScreenMap.Update(this, pos, anim.Image);
|
||||
}
|
||||
|
||||
IEnumerable<IRenderable> IEffect.Render(WorldRenderer wr) { yield break; }
|
||||
|
||||
IEnumerable<IRenderable> IEffectAnnotation.RenderAnnotation(WorldRenderer wr)
|
||||
{
|
||||
var screenPos = wr.Viewport.WorldToViewPx(wr.ScreenPxPosition(pos));
|
||||
return anim.RenderUI(wr, screenPos, WVec.Zero, 0, wr.Palette(palette));
|
||||
}
|
||||
}
|
||||
}
|
||||
86
OpenRA.Mods.Common/Effects/SpriteEffect.cs
Normal file
86
OpenRA.Mods.Common/Effects/SpriteEffect.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public class SpriteEffect : IEffect, ISpatiallyPartitionable
|
||||
{
|
||||
readonly World world;
|
||||
readonly string palette;
|
||||
readonly Animation anim;
|
||||
readonly Func<WPos> posFunc;
|
||||
readonly bool visibleThroughFog;
|
||||
readonly string sequence;
|
||||
WPos pos;
|
||||
int delay;
|
||||
bool initialized;
|
||||
|
||||
// Facing is last on these overloads partially for backwards compatibility with previous main ctor revision
|
||||
// and partially because most effects don't need it. The latter is also the reason for placement of 'delay'.
|
||||
public SpriteEffect(WPos pos, World world, string image, string sequence, string palette,
|
||||
bool visibleThroughFog = false, int delay = 0)
|
||||
: this(() => pos, () => WAngle.Zero, world, image, sequence, palette, visibleThroughFog, delay) { }
|
||||
|
||||
public SpriteEffect(Actor actor, World world, string image, string sequence, string palette,
|
||||
bool visibleThroughFog = false, int delay = 0)
|
||||
: this(() => actor.CenterPosition, () => WAngle.Zero, world, image, sequence, palette, visibleThroughFog, delay) { }
|
||||
|
||||
public SpriteEffect(WPos pos, WAngle facing, World world, string image, string sequence, string palette,
|
||||
bool visibleThroughFog = false, int delay = 0)
|
||||
: this(() => pos, () => facing, world, image, sequence, palette, visibleThroughFog, delay) { }
|
||||
|
||||
public SpriteEffect(Func<WPos> posFunc, Func<WAngle> facingFunc, World world, string image, string sequence, string palette,
|
||||
bool visibleThroughFog = false, int delay = 0)
|
||||
{
|
||||
this.world = world;
|
||||
this.posFunc = posFunc;
|
||||
this.palette = palette;
|
||||
this.sequence = sequence;
|
||||
this.visibleThroughFog = visibleThroughFog;
|
||||
this.delay = delay;
|
||||
pos = posFunc();
|
||||
anim = new Animation(world, image, facingFunc);
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (delay-- > 0)
|
||||
return;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
anim.PlayThen(sequence, () => world.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); }));
|
||||
world.ScreenMap.Add(this, pos, anim.Image);
|
||||
initialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim.Tick();
|
||||
|
||||
pos = posFunc();
|
||||
world.ScreenMap.Update(this, pos, anim.Image);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (!initialized || (!visibleThroughFog && world.FogObscures(pos)))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
return anim.Render(pos, wr.Palette(palette));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user