Merge pull request #3999 from Mailaender/moveflash

Brought back the MoveFlash
This commit is contained in:
Paul Chote
2013-11-02 15:35:29 -07:00
22 changed files with 178 additions and 92 deletions

View File

@@ -11,6 +11,7 @@ NEW:
Fixed base attack notification playing when allied engineers repaired your buildings.
Improved the ingame chat interface and input, with it defaulting to Team Chat.
Redesigned the settings panel.
Re-added move flashes.
Red Alert:
Added MAD Tank.
Fixed a crash in Monster Tank Madness.

View File

@@ -0,0 +1,41 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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 OpenRA.Effects;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Effects
{
public class MoveFlash : IEffect
{
Animation anim;
WPos pos;
public MoveFlash(WPos pos, World world)
{
this.pos = pos;
anim = new Animation("moveflsh");
anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this)));
}
public void Tick(World world)
{
anim.Tick();
}
public IEnumerable<IRenderable> Render(WorldRenderer wr)
{
return anim.Render(pos, WVec.Zero, 0, wr.Palette("moveflash"), 1f / wr.Viewport.Zoom);
}
}
}

View File

@@ -94,11 +94,6 @@ namespace OpenRA.Graphics
Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1;
}
public CPos ViewToWorld(int2 view)
{
return worldRenderer.Position(ViewToWorldPx(view)).ToCPos();
}
public int2 ViewToWorldPx(int2 view) { return (1f / Zoom * view.ToFloat2()).ToInt2() + TopLeft; }
public int2 WorldToViewPx(int2 world) { return (Zoom * (world - TopLeft).ToFloat2()).ToInt2(); }

View File

@@ -236,6 +236,7 @@
<Compile Include="Traits\World\ScreenMap.cs" />
<Compile Include="Traits\World\ActorMap.cs" />
<Compile Include="Widgets\HotkeyEntryWidget.cs" />
<Compile Include="Effects\MoveFlash.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -41,16 +41,15 @@ namespace OpenRA.Orders
.Where(o => o != null)
.ToArray();
var actorsInvolved = orders.Select(o => o.self).Distinct();
var actorsInvolved = orders.Select(o => o.Actor).Distinct();
if (actorsInvolved.Any())
yield return new Order("CreateGroup", actorsInvolved.First().Owner.PlayerActor, false)
{
TargetString = actorsInvolved.Select(a => a.ActorID).JoinWith(",")
};
foreach (var o in orders)
yield return CheckSameOrder(o.iot, o.trait.IssueOrder(o.self, o.iot, o.target, mi.Modifiers.HasModifier(Modifiers.Shift)));
yield return CheckSameOrder(o.Order, o.Trait.IssueOrder(o.Actor, o.Order, o.Target, mi.Modifiers.HasModifier(Modifiers.Shift)));
}
public void Tick(World world) { }
@@ -89,7 +88,7 @@ namespace OpenRA.Orders
.Where(o => o != null)
.ToArray();
var cursorName = orders.Select(o => o.cursor).FirstOrDefault();
var cursorName = orders.Select(o => o.Cursor).FirstOrDefault();
return cursorName ?? (useSelect ? "select" : "default");
}
@@ -103,9 +102,9 @@ namespace OpenRA.Orders
if (mi.Button == Game.mouseButtonPreference.Action)
{
foreach( var o in self.TraitsImplementing<IIssueOrder>()
foreach (var o in self.TraitsImplementing<IIssueOrder>()
.SelectMany(trait => trait.Orders
.Select(x => new { Trait = trait, Order = x } ))
.Select(x => new { Trait = trait, Order = x }))
.OrderByDescending(x => x.Order.OrderPriority))
{
var actorsAt = self.World.ActorMap.GetUnitsAt(target.CenterPosition.ToCPos()).ToList();
@@ -138,19 +137,19 @@ namespace OpenRA.Orders
class UnitOrderResult
{
public readonly Actor self;
public readonly IOrderTargeter iot;
public readonly IIssueOrder trait;
public readonly string cursor;
public readonly Target target;
public readonly Actor Actor;
public readonly IOrderTargeter Order;
public readonly IIssueOrder Trait;
public readonly string Cursor;
public readonly Target Target;
public UnitOrderResult(Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target)
public UnitOrderResult(Actor actor, IOrderTargeter order, IIssueOrder trait, string cursor, Target target)
{
this.self = self;
this.iot = iot;
this.trait = trait;
this.cursor = cursor;
this.target = target;
this.Actor = actor;
this.Order = order;
this.Trait = trait;
this.Cursor = cursor;
this.Target = target;
}
}
}

View File

@@ -97,9 +97,6 @@ namespace OpenRA.Traits
if (self.Destroyed)
return;
if (target.Type == TargetType.Actor && display)
w.Add(new FlashTarget(target.Actor));
var line = self.TraitOrDefault<DrawLineToTarget>();
if (line != null)
line.SetTarget(self, target, color, display);

View File

@@ -95,7 +95,7 @@ namespace OpenRA.Widgets
public void UpdateMouseover()
{
TooltipType = WorldTooltipType.None;
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
var cell = worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
if (!world.Map.IsInMap(cell))
return;

View File

@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Effects;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Orders;
@@ -21,14 +22,16 @@ namespace OpenRA.Widgets
{
public class WorldInteractionControllerWidget : Widget
{
protected readonly World world;
static readonly Actor[] NoActors = { };
protected readonly World World;
readonly WorldRenderer worldRenderer;
int2 dragStart, dragEnd;
[ObjectCreator.UseCtor]
public WorldInteractionControllerWidget(World world, WorldRenderer worldRenderer)
{
this.world = world;
this.World = world;
this.worldRenderer = worldRenderer;
}
@@ -37,14 +40,14 @@ namespace OpenRA.Widgets
var selbox = SelectionBox;
if (selbox == null)
{
foreach (var u in SelectActorsInBox(world, dragStart, dragStart, _ => true))
foreach (var u in SelectActorsInBox(World, dragStart, dragStart, _ => true))
worldRenderer.DrawRollover(u);
return;
}
Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First.ToFloat2(), selbox.Value.Second.ToFloat2(), Color.White);
foreach (var u in SelectActorsInBox(world, selbox.Value.First, selbox.Value.Second, _ => true))
foreach (var u in SelectActorsInBox(World, selbox.Value.First, selbox.Value.Second, _ => true))
worldRenderer.DrawRollover(u);
}
@@ -52,76 +55,75 @@ namespace OpenRA.Widgets
{
var xy = worldRenderer.Viewport.ViewToWorldPx(mi.Location);
var UseClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle;
var useClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle;
var HasBox = (SelectionBox != null) ? true : false;
var MultiClick = (mi.MultiTapCount >= 2) ? true : false;
var hasBox = (SelectionBox != null) ? true : false;
var multiClick = (mi.MultiTapCount >= 2) ? true : false;
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{
if (!TakeMouseFocus(mi))
return false;
dragStart = dragEnd = xy;
//place buildings
if (!UseClassicMouseStyle || (UseClassicMouseStyle && !world.Selection.Actors.Any()) )
ApplyOrders(world, xy, mi);
// place buildings
if (!useClassicMouseStyle || (useClassicMouseStyle && !World.Selection.Actors.Any()))
ApplyOrders(World, xy, mi);
}
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move)
dragEnd = xy;
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
{
if (UseClassicMouseStyle && HasMouseFocus)
if (useClassicMouseStyle && HasMouseFocus)
{
//order units around
if (!HasBox && world.Selection.Actors.Any() && !MultiClick)
// order units around
if (!hasBox && World.Selection.Actors.Any() && !multiClick)
{
ApplyOrders(world, xy, mi);
ApplyOrders(World, xy, mi);
YieldMouseFocus(mi);
return true;
}
}
if (world.OrderGenerator is UnitOrderGenerator)
if (World.OrderGenerator is UnitOrderGenerator)
{
if (MultiClick)
if (multiClick)
{
var unit = world.ScreenMap.ActorsAt(xy).FirstOrDefault();
var newSelection2 = SelectActorsInBox(world, worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.BottomRight,
var unit = World.ScreenMap.ActorsAt(xy).FirstOrDefault();
var newSelection2 = SelectActorsInBox(World, worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.BottomRight,
a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner);
world.Selection.Combine(world, newSelection2, true, false);
World.Selection.Combine(World, newSelection2, true, false);
}
else
{
var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true);
world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
var newSelection = SelectActorsInBox(World, dragStart, xy, _ => true);
World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
}
}
dragStart = dragEnd = xy;
YieldMouseFocus(mi);
}
if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move)
dragStart = dragEnd = xy;
if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down)
{
if (UseClassicMouseStyle)
world.Selection.Clear();
if (useClassicMouseStyle)
World.Selection.Clear();
if (!HasBox) // don't issue orders while selecting
ApplyOrders(world, xy, mi);
if (!hasBox) // don't issue orders while selecting
ApplyOrders(World, xy, mi);
}
return true;
}
public Pair<int2, int2>? SelectionBox
{
get
@@ -137,14 +139,33 @@ namespace OpenRA.Widgets
var pos = worldRenderer.Position(xy);
var orders = world.OrderGenerator.Order(world, pos.ToCPos(), mi).ToArray();
orders.Do(o => world.IssueOrder(o));
world.PlayVoiceForOrders(orders);
var flashed = false;
foreach (var o in orders)
{
if (!flashed)
{
if (o.TargetActor != null)
{
world.AddFrameEndTask(w => w.Add(new FlashTarget(o.TargetActor)));
flashed = true;
}
else if (o.Subject != world.LocalPlayer.PlayerActor && o.TargetLocation != CPos.Zero) // TODO: this filters building placement, but also suppport powers :(
{
world.AddFrameEndTask(w => w.Add(new MoveFlash(worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(mi.Location)), world)));
flashed = true;
}
}
world.IssueOrder(o);
}
}
public override string GetCursor(int2 screenPos)
{
return Sync.CheckSyncUnchanged(world, () =>
return Sync.CheckSyncUnchanged(World, () =>
{
// Always show an arrow while selecting
if (SelectionBox != null)
@@ -161,7 +182,7 @@ namespace OpenRA.Widgets
Modifiers = Game.GetModifierKeys()
};
return world.OrderGenerator.GetCursor(world, cell, mi);
return World.OrderGenerator.GetCursor(World, cell, mi);
});
}
@@ -172,18 +193,16 @@ namespace OpenRA.Widgets
if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9)
{
var group = (int)e.Key - (int)Keycode.NUMBER_0;
world.Selection.DoControlGroup(world, worldRenderer, group, e.Modifiers, e.MultiTapCount);
World.Selection.DoControlGroup(World, worldRenderer, group, e.Modifiers, e.MultiTapCount);
return true;
}
// Disable pausing for spectators
else if (Hotkey.FromKeyInput(e) == Game.Settings.Keys.PauseKey && world.LocalPlayer != null)
world.SetPauseState(!world.Paused);
else if (Hotkey.FromKeyInput(e) == Game.Settings.Keys.PauseKey && World.LocalPlayer != null) // Disable pausing for spectators
World.SetPauseState(!World.Paused);
}
return false;
}
static readonly Actor[] NoActors = {};
IEnumerable<Actor> SelectActorsInBox(World world, int2 a, int2 b, Func<Actor, bool> cond)
{
return world.ScreenMap.ActorsInBox(a, b)

View File

@@ -81,7 +81,7 @@ namespace OpenRA
public readonly ActorMap ActorMap;
public readonly ScreenMap ScreenMap;
public void IssueOrder( Order o ) { orderManager.IssueOrder( o ); } /* avoid exposing the OM to mod code */
public void IssueOrder(Order o) { orderManager.IssueOrder(o); } /* avoid exposing the OM to mod code */
IOrderGenerator orderGenerator_;
public IOrderGenerator OrderGenerator

View File

@@ -259,7 +259,9 @@ namespace OpenRA.Mods.RA.Move
{
if (order is MoveOrderTargeter)
{
if (Info.OnRails) return null;
if (Info.OnRails)
return null;
return new Order("Move", self, queued) { TargetLocation = target.CenterPosition.ToCPos() };
}
return null;

2
OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs Executable file → Normal file
View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.RA.Orders
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) { yield break; }
public void RenderAfterWorld(WorldRenderer wr, World world)
{
var position = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var position = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var topLeft = position - FootprintUtils.AdjustForBuildingSize(BuildingInfo);
var actorInfo = Rules.Info[Building];

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA
// Find the queue with the target actor
var queue = w.ActorsWithTrait<ProductionQueue>()
.Where(p => p.Actor.Owner == self.Owner &&
p.Trait.CurrentItem() != null &&
p.Trait.CurrentItem() != null &&
p.Trait.CurrentItem().Item == order.TargetString &&
p.Trait.CurrentItem().RemainingTime == 0)
.Select(p => p.Trait)

6
OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs Executable file → Normal file
View File

@@ -138,7 +138,7 @@ namespace OpenRA.Mods.RA
public void RenderAfterWorld(WorldRenderer wr, World world)
{
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var targetUnits = power.UnitsInRange(xy);
foreach (var unit in targetUnits)
if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility())
@@ -147,7 +147,7 @@ namespace OpenRA.Mods.RA
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var tiles = world.FindTilesInCircle(xy, range);
var pal = wr.Palette("terrain");
foreach (var t in tiles)
@@ -226,7 +226,7 @@ namespace OpenRA.Mods.RA
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var pal = wr.Palette("terrain");
// Source tiles

4
OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs Executable file → Normal file
View File

@@ -90,14 +90,14 @@ namespace OpenRA.Mods.RA
public void RenderAfterWorld(WorldRenderer wr, World world)
{
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
foreach (var unit in power.UnitsInRange(xy))
wr.DrawSelectionBox(unit, Color.Red);
}
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var pal = wr.Palette("terrain");
foreach (var t in world.FindTilesInCircle(xy, range))
yield return new SpriteRenderable(tile, t.CenterPosition, WVec.Zero, -511, pal, 1f, true);

View File

@@ -257,6 +257,12 @@ World:
G: 255
B: 255
A: 128
PaletteFromRGBA@moveflash:
Name: moveflash
R: 255
G: 255
B: 255
A: 64
PaletteFromRGBA@disabled:
Name: disabled
R: 0

View File

@@ -304,4 +304,10 @@ icon:
ioncannon: ionicnh
Start: 0
abomb: atomicnh
Start: 0
Start: 0
moveflsh:
idle:
Start: 0
Length: *
Tick: 80

View File

@@ -411,12 +411,11 @@ World:
G: 255
B: 255
A: 128
PaletteFromRGBA@invuln:
Name: invuln
R: 128
G: 0
B: 0
A: 128
PaletteFromR8@moveflash:
Name: moveflash
Filename: DATA.R8
Offset: 2572352
A: 64
PaletteFromRGBA@disabled:
Name: disabled
R: 0

View File

@@ -297,4 +297,11 @@ spicebloom:
idle: DATA.R8
Start: 109
ZOffset: -511
Offset: -16,-16
Offset: -16,-16
moveflsh:
idle: DATA.R8
Start: 3621
Length: 5
Tick: 80
BlendMode: Subtractive

View File

@@ -587,6 +587,12 @@ World:
G: 255
B: 255
A: 128
PaletteFromRGBA@moveflash:
Name: moveflash
R: 255
G: 255
B: 255
A: 64
PaletteFromRGBA@invuln:
Name: invuln
R: 128

View File

@@ -162,6 +162,7 @@ moveflsh:
idle:
Start: 0
Length: *
Tick: 80
select:
repair:

View File

@@ -85,12 +85,12 @@ World:
G: 255
B: 255
A: 128
PaletteFromRGBA@invuln:
Name: invuln
R: 128
G: 0
B: 0
A: 128
PaletteFromRGBA@moveflash:
Name: moveflash
R: 255
G: 255
B: 255
A: 64
PaletteFromRGBA@disabled:
Name: disabled
R: 0

View File

@@ -242,4 +242,10 @@ crystal4:
torpedo:
idle:
Start: 0
Length: *
Length: *
moveflsh:
idle:
Start: 0
Length: *
Tick: 80